Version in base suite: 60.9.0-1~deb10u1 Version in overlay suite: 68.3.0-2~deb10u1 Base version: thunderbird_68.3.0-2~deb10u1 Target version: thunderbird_68.4.1-1~deb10u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/t/thunderbird/thunderbird_68.3.0-2~deb10u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/t/thunderbird/thunderbird_68.4.1-1~deb10u1.dsc .cron.yml | 20 .taskcluster.yml | 2 Cargo.lock | 29 accessible/ipc/win/handler/AccessibleHandler.cpp | 7 accessible/windows/msaa/AccessibleWrap.cpp | 21 browser/app/blocklist.xml | 887 - browser/components/customizableui/test/browser_exit_background_customize_mode.js | 5 browser/components/enterprisepolicies/Policies.jsm | 7 browser/components/enterprisepolicies/helpers/BookmarksPolicies.jsm | 26 browser/components/enterprisepolicies/schemas/policies-schema.json | 23 browser/components/enterprisepolicies/tests/browser/404.sjs | 3 browser/components/enterprisepolicies/tests/browser/browser.ini | 1 browser/components/enterprisepolicies/tests/browser/browser_policies_notice_in_aboutpreferences.js | 4 browser/components/enterprisepolicies/tests/xpcshell/test_empty_policy.js | 32 browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini | 1 browser/components/originattributes/test/browser/browser.ini | 2 browser/components/search/SearchTelemetry.jsm | 167 browser/components/search/test/unit/test_urlTelemetry.js | 349 browser/components/sessionstore/test/browser_duplicate_history.js | 5 browser/config/version.txt | 2 browser/config/version_display.txt | 2 build/moz.configure/toolchain.configure | 15 comm/.gecko_rev.yml | 2 comm/calendar/base/content/calendar-month-base-view.js | 11 comm/calendar/base/content/calendar-multiday-base-view.js | 11 comm/calendar/base/themes/common/calendar-task-tree.css | 4 comm/calendar/base/themes/common/dialogs/calendar-event-dialog.css | 9 comm/calendar/base/themes/common/icons/edit.svg | 2 comm/calendar/resources/skin/datetimepickers.css | 22 comm/chat/chat-prefs.js | 2 comm/chat/modules/DNS.jsm | 437 comm/chat/modules/moz.build | 1 comm/ldap/xpcom/src/nsLDAPOperation.cpp | 1 comm/mail/base/content/folderPane.js | 11 comm/mail/base/content/mailWindowOverlay.js | 25 comm/mail/base/content/messenger.css | 4 comm/mail/base/content/msgMail3PaneWindow.js | 4 comm/mail/base/content/nsContextMenu.js | 25 comm/mail/base/modules/DNS.jsm | 473 comm/mail/base/modules/moz.build | 1 comm/mail/components/accountcreation/content/emailWizard.js | 122 comm/mail/components/accountcreation/content/emailWizard.xul | 16 comm/mail/components/accountcreation/content/fetchConfig.js | 86 comm/mail/components/accountcreation/content/util.js | 32 comm/mail/components/extensions/parent/ext-mail.js | 30 comm/mail/components/extensions/parent/ext-messages.js | 21 comm/mail/components/extensions/test/browser/browser.ini | 1 comm/mail/components/extensions/test/browser/browser_ext_menus.js | 136 comm/mail/components/extensions/test/browser/browser_ext_windows_types.js | 14 comm/mail/components/extensions/test/browser/data/content.html | 11 comm/mail/components/extensions/test/xpcshell/test_ext_messages.js | 19 comm/mail/config/version.txt | 2 comm/mail/config/version_display.txt | 2 comm/mail/installer/allowed-dupes.mn | 3 comm/mail/locales/l10n-changesets.json | 2 comm/mail/themes/addons/dark/manifest.json | 2 comm/mail/themes/linux/mail/accountCreation.css | 4 comm/mail/themes/linux/mail/folderPane.css | 2 comm/mail/themes/osx/mail/folderPane.css | 2 comm/mail/themes/osx/mail/messageIcons.css | 2 comm/mail/themes/shared/mail/accountCreation.css | 11 comm/mail/themes/shared/mail/icons/search-not-found.svg | 6 comm/mail/themes/shared/mail/mailWindow1.css | 2 comm/mail/themes/windows/mail/accountCreation.css | 2 comm/mail/themes/windows/mail/compose/messengercompose.css | 2 comm/mail/themes/windows/mail/folderPane.css | 2 comm/mailnews/imap/public/nsIImapFlagAndUidState.idl | 2 comm/mailnews/imap/src/nsImapFlagAndUidState.cpp | 19 comm/mailnews/imap/src/nsImapFlagAndUidState.h | 2 comm/mailnews/imap/src/nsImapMailFolder.cpp | 91 comm/mailnews/imap/src/nsImapMailFolder.h | 3 comm/mailnews/imap/src/nsImapServerResponseParser.cpp | 64 comm/mailnews/mailnews.js | 2 comm/taskcluster/ci/release-update-verify-config/kind.yml | 2 config/milestone.txt | 2 debian/changelog | 36 debian/patches/debian-hacks/Add-another-preferences-directory-for-applications-p.patch | 2 debian/patches/debian-hacks/Build-against-system-libjsoncpp.patch | 2 debian/patches/debian-hacks/Downgrade-SQlite-version-to-3.27.2.patch | 2 debian/patches/debian-hacks/Set-program-name-from-the-remoting-name.patch | 4 debian/patches/debian-hacks/stop-configure-if-with-system-bz2-was-passed-but-no-.patch | 2 debian/patches/fixes/Update-bindgen-in-ESR68.-r-glandium-a-RyanVM.patch | 1404 -- debian/patches/porting-arm/Reduce-memory-usage-while-linking-on-arm-el-hf-platforms.patch | 4 debian/patches/porting-armel/Bug-1463035-Remove-MOZ_SIGNAL_TRAMPOLINE.-r-darchons.patch | 4 debian/patches/porting-kfreebsd-hurd/FTBFS-hurd-fixing-unsupported-platform-Hurd.patch | 2 debian/patches/porting-kfreebsd-hurd/LDAP-support-building-on-GNU-kFreeBSD-and-GNU-Hurd.patch | 18 debian/patches/porting-m68k/Add-m68k-support-to-Thunderbird.patch | 6 debian/patches/porting-sh4/Add-sh4-support-to-Thunderbird.patch | 4 debian/patches/prefs/Don-t-auto-disable-extensions-in-system-directories.patch | 2 debian/patches/prefs/Set-javascript.options.showInConsole.patch | 6 debian/patches/series | 1 devtools/client/netmonitor/test/browser.ini | 2 devtools/server/tests/unit/head_dbg.js | 22 devtools/server/tests/unit/test_addon_events.js | 5 devtools/server/tests/unit/test_addon_reload.js | 4 devtools/server/tests/unit/test_addons_actor.js | 8 dom/base/Document.cpp | 181 dom/base/Document.h | 4 dom/base/nsContentUtils.cpp | 2 dom/base/nsGlobalWindowOuter.cpp | 8 dom/base/nsTreeSanitizer.cpp | 156 dom/base/nsTreeSanitizer.h | 9 dom/base/nsXHTMLContentSerializer.cpp | 2 dom/broadcastchannel/tests/mochitest.ini | 1 dom/cache/StreamControl.cpp | 3 dom/events/test/mochitest.ini | 2 dom/indexedDB/IDBEvents.cpp | 3 dom/ipc/ContentParent.cpp | 2 dom/localstorage/LSWriteOptimizer.cpp | 11 dom/media/test/mochitest.ini | 2 dom/plugins/base/nsNPAPIPluginStreamListener.cpp | 2 dom/plugins/ipc/PluginInstanceChild.cpp | 2 dom/presentation/PresentationConnectionList.cpp | 4 dom/presentation/ipc/PresentationParent.cpp | 2 dom/presentation/tests/xpcshell/xpcshell.ini | 1 dom/webbrowserpersist/nsWebBrowserPersist.cpp | 6 dom/workers/ScriptLoader.cpp | 4 dom/workers/Worker.cpp | 8 gfx/ycbcr/YCbCrUtils.cpp | 15 js/public/ProfilingStack.h | 4 js/src/build/Makefile.in | 5 js/src/build/js-config.in | 2 js/src/build/js.pc.in | 2 js/src/jit/AliasAnalysis.cpp | 4 js/src/jit/MIR.h | 9 js/src/js-config.h.in | 20 js/src/jsapi.cpp | 8 js/src/jstypes.h | 7 js/xpconnect/src/XPCVariant.cpp | 10 layout/base/PresShell.cpp | 34 layout/base/nsDocumentViewer.cpp | 35 layout/base/nsLayoutUtils.cpp | 2 layout/base/nsPresContext.cpp | 32 layout/base/nsPresContext.h | 12 layout/generic/nsSubDocumentFrame.cpp | 39 layout/painting/RetainedDisplayListBuilder.cpp | 22 layout/painting/nsCSSRendering.cpp | 2 layout/painting/nsDisplayList.cpp | 18 layout/printing/nsPrintJob.cpp | 17 layout/style/StyleSheet.cpp | 13 layout/style/nsStyleStruct.cpp | 2 layout/style/test/gtest/StyloParsingBench.cpp | 3 layout/tables/nsTableFrame.cpp | 4 layout/xul/nsXULPopupManager.cpp | 2 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-alarms.properties | 34 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-event-dialog-attendees.properties | 20 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-event-dialog.dtd | 691 - lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-event-dialog.properties | 220 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-extract.properties | 76 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-invitations-dialog.dtd | 10 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-invitations-dialog.properties | 12 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-occurrence-prompt.properties | 98 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar-subscriptions-dialog.dtd | 16 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar.dtd | 467 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendar.properties | 470 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendarCreation.dtd | 62 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/calendarCreation.properties | 4 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/categories.properties | 2 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/dateFormat.properties | 98 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/dialogs/calendar-event-dialog-reminder.dtd | 20 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/global.dtd | 86 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/menuOverlay.dtd | 30 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/migration.dtd | 10 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/migration.properties | 12 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/preferences/alarms.dtd | 32 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/preferences/categories.dtd | 24 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/preferences/general.dtd | 52 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/preferences/preferences.dtd | 11 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/preferences/views.dtd | 45 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/provider-uninstall.dtd | 12 lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/timezones.properties | 884 - lightning-l10n/hy-AM/chrome/calendar-hy-AM/locale/hy-AM/calendar/wcap.properties | 24 lightning-l10n/hy-AM/chrome/lightning-hy-AM/locale/hy-AM/lightning/lightning-toolbar.dtd | 54 lightning-l10n/hy-AM/chrome/lightning-hy-AM/locale/hy-AM/lightning/lightning.dtd | 116 lightning-l10n/hy-AM/chrome/lightning-hy-AM/locale/hy-AM/lightning/lightning.properties | 116 media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc | 16 media/webrtc/trunk/webrtc/modules/video_capture/linux/video_capture_linux.cc | 19 mfbt/HashTable.h | 23 mobile/android/base/java/org/mozilla/gecko/BrowserApp.java | 8 mobile/android/base/java/org/mozilla/gecko/db/LocalBrowserDB.java | 2 mobile/android/base/java/org/mozilla/gecko/telemetry/pingbuilders/TelemetryCorePingBuilder.java | 34 mobile/android/config/version-files/beta/version.txt | 2 mobile/android/config/version-files/beta/version_display.txt | 2 mobile/android/config/version-files/nightly/version.txt | 2 mobile/android/config/version-files/nightly/version_display.txt | 2 mobile/android/config/version-files/release/version.txt | 2 mobile/android/config/version-files/release/version_display.txt | 2 mobile/locales/l10n-changesets.json | 184 modules/libjar/MmapFaultHandler.cpp | 176 modules/libjar/MmapFaultHandler.h | 89 modules/libjar/moz.build | 1 modules/libjar/nsJARInputStream.cpp | 5 modules/libjar/nsZipArchive.cpp | 53 modules/libjar/nsZipArchive.h | 20 modules/libjar/test/unit/test_bug1550815.js | 32 modules/libjar/test/unit/xpcshell.ini | 3 modules/libpref/init/StaticPrefList.h | 8 netwerk/dns/effective_tld_names.dat | 118 netwerk/protocol/http/nsHttpChannel.cpp | 7 python/mozbuild/mozbuild/nodeutil.py | 2 security/manager/ssl/SSLServerCertVerification.cpp | 1 security/manager/ssl/StaticHPKPins.h | 2 security/manager/ssl/nsNSSCertHelper.cpp | 4 security/manager/ssl/nsNSSCertificate.cpp | 11 security/manager/ssl/nsSTSPreloadList.inc | 6296 ++++++---- security/sandbox/chromium/sandbox/win/src/target_process.cc | 35 security/sandbox/linux/SandboxFilter.cpp | 7 services/settings/dumps/blocklists/addons.json | 2 services/settings/dumps/blocklists/plugins.json | 2 services/settings/dumps/security-state/intermediates.json | 2 servo/components/style/stylesheets/mod.rs | 1 servo/components/style/stylesheets/namespace_rule.rs | 14 servo/components/style/stylesheets/stylesheet.rs | 90 servo/ports/geckolib/glue.rs | 30 servo/ports/geckolib/stylesheet_loader.rs | 1 sourcestamp.txt | 6 taskcluster/ci/config.yml | 1 taskcluster/ci/cron-bouncer-check/kind.yml | 7 taskcluster/ci/l10n-bump/kind.yml | 127 taskcluster/ci/release-bouncer-aliases/kind.yml | 7 taskcluster/ci/release-snap-push/kind.yml | 3 taskcluster/ci/release-update-verify-config-next/kind.yml | 98 taskcluster/ci/release-update-verify-next/kind.yml | 73 taskcluster/ci/toolchain/clang.yml | 6 taskcluster/docker/recipes/install-node.sh | 6 taskcluster/docs/attributes.rst | 9 taskcluster/docs/kinds.rst | 4 taskcluster/scripts/misc/build-clang-8-mingw.sh | 25 taskcluster/scripts/misc/repack-node.sh | 18 taskcluster/taskgraph/generator.py | 7 taskcluster/taskgraph/target_tasks.py | 10 taskcluster/taskgraph/test/test_generator.py | 1 taskcluster/taskgraph/transforms/release_version_bump.py | 10 taskcluster/taskgraph/transforms/repackage_partner.py | 2 taskcluster/taskgraph/transforms/task.py | 40 taskcluster/taskgraph/util/docker.py | 12 testing/mozharness/configs/releases/bouncer_firefox_beta.py | 44 testing/mozharness/configs/releases/bouncer_firefox_devedition.py | 49 testing/mozharness/configs/releases/bouncer_firefox_esr.py | 73 testing/mozharness/configs/releases/bouncer_firefox_nightly.py | 75 testing/mozharness/configs/releases/bouncer_firefox_release.py | 44 testing/mozharness/scripts/release/bouncer_check.py | 2 testing/web-platform/tests/workers/WorkerGlobalScope-close.html | 27 testing/xpcshell/runxpcshelltests.py | 5 third_party/rust/bindgen/.cargo-checksum.json | 2 third_party/rust/bindgen/Cargo.lock | 452 third_party/rust/bindgen/Cargo.toml | 6 third_party/rust/bindgen/csmith-fuzzing/README.md | 65 third_party/rust/bindgen/src/codegen/bitfield_unit.rs | 11 third_party/rust/bindgen/src/codegen/helpers.rs | 6 third_party/rust/bindgen/src/codegen/mod.rs | 98 third_party/rust/bindgen/src/features.rs | 9 third_party/rust/bindgen/src/ir/analysis/has_vtable.rs | 27 third_party/rust/bindgen/src/ir/analysis/sizedness.rs | 41 third_party/rust/bindgen/src/ir/comp.rs | 4 third_party/rust/bindgen/src/ir/derive.rs | 26 third_party/rust/bindgen/src/ir/enum_ty.rs | 4 third_party/rust/bindgen/src/ir/function.rs | 4 third_party/rust/bindgen/src/lib.rs | 56 third_party/rust/bindgen/src/main.rs | 6 third_party/rust/bindgen/src/options.rs | 11 third_party/rust/cssparser/.cargo-checksum.json | 2 third_party/rust/cssparser/Cargo.toml | 2 third_party/rust/cssparser/README.md | 2 third_party/rust/cssparser/src/rules_and_declarations.rs | 2 third_party/rust/cssparser/src/serializer.rs | 13 third_party/rust/cssparser/src/tokenizer.rs | 8 thunderbird-l10n/ar/manifest.json | 2 thunderbird-l10n/ast/manifest.json | 2 thunderbird-l10n/be/manifest.json | 2 thunderbird-l10n/bg/manifest.json | 2 thunderbird-l10n/br/manifest.json | 2 thunderbird-l10n/ca/manifest.json | 2 thunderbird-l10n/cak/manifest.json | 2 thunderbird-l10n/cs/manifest.json | 2 thunderbird-l10n/cy/manifest.json | 2 thunderbird-l10n/da/manifest.json | 2 thunderbird-l10n/de/manifest.json | 2 thunderbird-l10n/dsb/manifest.json | 2 thunderbird-l10n/el/manifest.json | 2 thunderbird-l10n/en-GB/manifest.json | 2 thunderbird-l10n/es-AR/manifest.json | 2 thunderbird-l10n/es-ES/manifest.json | 2 thunderbird-l10n/et/manifest.json | 2 thunderbird-l10n/eu/manifest.json | 2 thunderbird-l10n/fi/manifest.json | 2 thunderbird-l10n/fr/manifest.json | 2 thunderbird-l10n/fy-NL/manifest.json | 2 thunderbird-l10n/ga-IE/manifest.json | 2 thunderbird-l10n/gd/manifest.json | 2 thunderbird-l10n/gl/manifest.json | 2 thunderbird-l10n/he/manifest.json | 2 thunderbird-l10n/hr/manifest.json | 2 thunderbird-l10n/hsb/manifest.json | 2 thunderbird-l10n/hu/manifest.json | 2 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/chat/xmpp.properties | 23 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/editor/EdColorPicker.dtd | 10 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/editor/EdDialogOverlay.dtd | 6 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/accountCreation.dtd | 14 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/accountCreation.properties | 46 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/accountCreationModel.properties | 3 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/addons.properties | 2 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/addressbook/abCard.dtd | 168 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/addressbook/abContactsPanel.dtd | 14 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/addressbook/abMainWindow.dtd | 30 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/addressbook/abResultsPane.dtd | 36 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/addressbook/addressBook.properties | 101 thunderbird-l10n/hy-AM/chrome/hy-AM/locale/hy-AM/messenger/msgAccountCentral.dtd | 5 thunderbird-l10n/hy-AM/localization/hy-AM/toolkit/about/aboutAddons.ftl | 51 thunderbird-l10n/hy-AM/localization/hy-AM/toolkit/about/aboutSupport.ftl | 11 thunderbird-l10n/hy-AM/localization/hy-AM/toolkit/about/abuseReports.ftl | 3 thunderbird-l10n/hy-AM/localization/hy-AM/toolkit/main-window/editmenu.ftl | 3 thunderbird-l10n/hy-AM/manifest.json | 4 thunderbird-l10n/id/manifest.json | 2 thunderbird-l10n/is/manifest.json | 2 thunderbird-l10n/it/manifest.json | 2 thunderbird-l10n/ja/manifest.json | 2 thunderbird-l10n/ka/manifest.json | 2 thunderbird-l10n/kab/manifest.json | 2 thunderbird-l10n/kk/manifest.json | 2 thunderbird-l10n/ko/manifest.json | 2 thunderbird-l10n/lt/manifest.json | 2 thunderbird-l10n/ms/manifest.json | 2 thunderbird-l10n/nb-NO/manifest.json | 2 thunderbird-l10n/nl/manifest.json | 2 thunderbird-l10n/nn-NO/manifest.json | 2 thunderbird-l10n/pl/manifest.json | 2 thunderbird-l10n/pt-BR/manifest.json | 2 thunderbird-l10n/pt-PT/manifest.json | 2 thunderbird-l10n/rm/manifest.json | 2 thunderbird-l10n/ro/manifest.json | 2 thunderbird-l10n/ru/manifest.json | 2 thunderbird-l10n/si/manifest.json | 2 thunderbird-l10n/sk/manifest.json | 2 thunderbird-l10n/sl/manifest.json | 2 thunderbird-l10n/sq/manifest.json | 2 thunderbird-l10n/sr/manifest.json | 2 thunderbird-l10n/sv-SE/manifest.json | 2 thunderbird-l10n/tr/manifest.json | 2 thunderbird-l10n/uk/manifest.json | 2 thunderbird-l10n/uz/manifest.json | 2 thunderbird-l10n/vi/manifest.json | 2 thunderbird-l10n/zh-CN/manifest.json | 2 thunderbird-l10n/zh-TW/manifest.json | 2 toolkit/components/enterprisepolicies/EnterprisePolicies.js | 23 toolkit/components/enterprisepolicies/tests/moz.build | 2 toolkit/components/enterprisepolicies/tests/xpcshell/head.js | 73 toolkit/components/enterprisepolicies/tests/xpcshell/test_empty.js | 16 toolkit/components/enterprisepolicies/tests/xpcshell/xpcshell.ini | 5 toolkit/components/extensions/test/browser/browser_ext_themes_ntp_colors_perwindow.js | 11 toolkit/components/extensions/test/xpcshell/test_ext_downloads_misc.js | 50 toolkit/components/startup/nsAppStartup.cpp | 5 toolkit/components/telemetry/docs/data/core-ping.rst | 272 toolkit/components/telemetry/tests/unit/xpcshell.ini | 1 toolkit/mozapps/extensions/internal/XPIInstall.jsm | 21 toolkit/mozapps/extensions/test/xpcshell/test_recommendations.js | 30 toolkit/mozapps/update/common/commonupdatedir.cpp | 13 toolkit/mozapps/update/tests/data/xpcshellUtilsAUS.js | 14 toolkit/mozapps/update/updater/updater.cpp | 50 toolkit/xre/AssembleCmdLine.h | 228 toolkit/xre/moz.build | 1 toolkit/xre/test/gtest/TestAssembleCommandLineWin.cpp | 96 toolkit/xre/test/gtest/moz.build | 5 uriloader/exthandler/win/nsMIMEInfoWin.cpp | 21 widget/gtk/nsApplicationChooser.cpp | 5 widget/gtk/nsLookAndFeel.cpp | 54 widget/gtk/nsLookAndFeel.h | 4 xpcom/io/nsLocalFileWin.cpp | 86 xpcom/threads/nsProcessCommon.cpp | 112 369 files changed, 12101 insertions(+), 8165 deletions(-) diff -Nru thunderbird-68.3.0/.cron.yml thunderbird-68.4.1/.cron.yml --- thunderbird-68.3.0/.cron.yml 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/.cron.yml 2020-01-09 03:28:20.000000000 +0000 @@ -140,17 +140,25 @@ treeherder-symbol: Rel target-tasks-method: cron_bouncer_check run-on-projects: + - mozilla-central - mozilla-beta - mozilla-release + - mozilla-esr68 when: by-project: # No default branch + mozilla-central: + - {hour: 7, minute: 0} + - {hour: 19, minute: 0} mozilla-beta: - {hour: 7, minute: 0} - {hour: 19, minute: 0} mozilla-release: - {hour: 7, minute: 0} - {hour: 19, minute: 0} + mozilla-esr68: + - {hour: 7, minute: 0} + - {hour: 19, minute: 0} - name: periodic-update job: @@ -178,3 +186,15 @@ # No default branch mozilla-central: - {weekday: 'Monday', hour: 10, minute: 0} + + - name: l10n-bumper + job: + type: decision-task + treeherder-symbol: l10n-bump + target-tasks-method: l10n_bump + run-on-projects: + - mozilla-central + - mozilla-beta + - mozilla-esr68 + when: + - {minute: 45} diff -Nru thunderbird-68.3.0/.taskcluster.yml thunderbird-68.4.1/.taskcluster.yml --- thunderbird-68.3.0/.taskcluster.yml 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/.taskcluster.yml 2020-01-09 03:28:20.000000000 +0000 @@ -211,7 +211,7 @@ ACTION_PARAMETERS: {$json: {$eval: 'parameters'}} cache: - level-${repository.level}-checkouts-sparse-v2: /builds/worker/checkouts + gecko-level-${repository.level}-checkouts-sparse-v2: /builds/worker/checkouts features: taskclusterProxy: true diff -Nru thunderbird-68.3.0/Cargo.lock thunderbird-68.4.1/Cargo.lock --- thunderbird-68.3.0/Cargo.lock 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/Cargo.lock 2020-01-09 03:28:21.000000000 +0000 @@ -170,7 +170,7 @@ name = "baldrdash" version = "0.1.0" dependencies = [ - "bindgen 0.49.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bindgen 0.49.4 (registry+https://github.com/rust-lang/crates.io-index)", "cranelift-codegen 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=cc216b46b35a797d03c0f3e8b16a2096f1c6db61)", "cranelift-wasm 0.30.0 (git+https://github.com/CraneStation/Cranelift?rev=cc216b46b35a797d03c0f3e8b16a2096f1c6db61)", "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -232,14 +232,13 @@ [[package]] name = "bindgen" -version = "0.49.1" +version = "0.49.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "cexpr 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", "clang-sys 0.28.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -736,7 +735,7 @@ [[package]] name = "cssparser" -version = "0.25.5" +version = "0.25.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1204,7 +1203,7 @@ version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)", "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.51 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1475,7 +1474,7 @@ name = "js" version = "0.1.4" dependencies = [ - "bindgen 0.49.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bindgen 0.49.4 (registry+https://github.com/rust-lang/crates.io-index)", "cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1681,7 +1680,7 @@ version = "0.0.1" dependencies = [ "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)", "hashglobe 0.1.0", "selectors 0.21.0", @@ -2667,7 +2666,7 @@ version = "0.21.0" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2881,10 +2880,10 @@ "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bindgen 0.49.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bindgen 0.49.4 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)", "fallible 0.0.1", @@ -2946,7 +2945,7 @@ dependencies = [ "app_units 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)", "euclid 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "malloc_size_of 0.0.1", @@ -2962,7 +2961,7 @@ version = "0.0.1" dependencies = [ "atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)", "cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", "geckoservo 0.0.1", @@ -3137,7 +3136,7 @@ name = "to_shmem" version = "0.0.1" dependencies = [ - "cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)", "servo_arc 0.1.1", "smallbitvec 2.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3758,7 +3757,7 @@ "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" "checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff" "checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0" -"checksum bindgen 0.49.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6bd7710ac8399ae1ebe1e3aac7c9047c4f39f2c94b33c997f482f49e96991f7c" +"checksum bindgen 0.49.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4c07087f3d5731bf3fb375a81841b99597e25dc11bd3bc72d16d43adf6624a6e" "checksum binjs_meta 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "430239e4551e42b80fa5d92322ac80ea38c9dda56e5d5582e057e2288352b71a" "checksum bit-set 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6f1efcc46c18245a69c38fcc5cc650f16d3a59d034f3106e9ed63748f695730a" "checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" @@ -3807,7 +3806,7 @@ "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9" "checksum crossbeam-utils 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d636a8b3bcc1b409d7ffd3facef8f21dcb4009626adbd0c5e6c4305c07253c7b" "checksum crossbeam-utils 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "41ee4864f4797060e52044376f7d107429ce1fb43460021b126424b7180ee21a" -"checksum cssparser 0.25.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e06795910fc2f585a75bdc9690fbcc51e83519f07b6eb981db43944643c04933" +"checksum cssparser 0.25.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a921abc45ea75c2c817d951caeda31b94539d09a6b5e8d58a857b3b35c9c3894" "checksum cssparser-macros 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "f3a5383ae18dbfdeb569ed62019f5bddb2a95cd2d3833313c475a0d014777805" "checksum cstr 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b6557bdb1dc9647eae1cf7f5601b14cd45fc3c7ccf2df618387416fe542da6ea" "checksum cstr-macros 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0472c17c83d3ec1af32fb6ee2b3ad56ae0b6e69355d63d1d30602055c34324a8" diff -Nru thunderbird-68.3.0/accessible/ipc/win/handler/AccessibleHandler.cpp thunderbird-68.4.1/accessible/ipc/win/handler/AccessibleHandler.cpp --- thunderbird-68.3.0/accessible/ipc/win/handler/AccessibleHandler.cpp 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/accessible/ipc/win/handler/AccessibleHandler.cpp 2020-01-09 03:28:20.000000000 +0000 @@ -893,8 +893,11 @@ HRESULT AccessibleHandler::put_accValue(VARIANT varChild, BSTR szValue) { - // This matches AccessibleWrap - return E_NOTIMPL; + HRESULT hr = ResolveIA2(); + if (FAILED(hr)) { + return hr; + } + return mIA2PassThru->put_accValue(varChild, szValue); } /*** IAccessible2 ***/ diff -Nru thunderbird-68.3.0/accessible/windows/msaa/AccessibleWrap.cpp thunderbird-68.4.1/accessible/windows/msaa/AccessibleWrap.cpp --- thunderbird-68.3.0/accessible/windows/msaa/AccessibleWrap.cpp 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/accessible/windows/msaa/AccessibleWrap.cpp 2020-01-09 03:28:21.000000000 +0000 @@ -12,6 +12,7 @@ #include "mozilla/a11y/DocAccessibleParent.h" #include "EnumVariant.h" #include "GeckoCustom.h" +#include "HyperTextAccessible-inl.h" #include "nsAccUtils.h" #include "nsCoreUtils.h" #include "nsIAccessibleEvent.h" @@ -1015,7 +1016,25 @@ AccessibleWrap::put_accValue( /* [optional][in] */ VARIANT varChild, /* [in] */ BSTR szValue) { - return E_NOTIMPL; + RefPtr accessible; + HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible)); + if (FAILED(hr)) { + return hr; + } + + if (accessible) { + return accessible->put_accValue(kVarChildIdSelf, szValue); + } + + HyperTextAccessible* ht = AsHyperText(); + if (!ht) { + return E_NOTIMPL; + } + + uint32_t length = ::SysStringLen(szValue); + nsAutoString text(szValue, length); + ht->ReplaceText(text); + return S_OK; } //////////////////////////////////////////////////////////////////////////////// diff -Nru thunderbird-68.3.0/browser/app/blocklist.xml thunderbird-68.4.1/browser/app/blocklist.xml --- thunderbird-68.3.0/browser/app/blocklist.xml 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/app/blocklist.xml 2020-01-09 03:28:21.000000000 +0000 @@ -1,14 +1,10 @@ - + - - - - @@ -25,10 +21,6 @@ - - - - @@ -53,10 +45,6 @@ - - - - @@ -89,15 +77,6 @@ - - - - - - - - - @@ -134,10 +113,6 @@ - - - - browser.startup.homepage @@ -203,10 +178,6 @@ - - - - @@ -231,10 +202,6 @@ - - - - browser.startup.homepage @@ -242,10 +209,6 @@ - - - - @@ -283,10 +246,6 @@ - - - - browser.startup.homepage @@ -298,10 +257,6 @@ - - - - @@ -325,22 +280,6 @@ - - - - - - - - - - - - - - - - @@ -349,14 +288,6 @@ - - - - - - - - @@ -373,29 +304,14 @@ - - - - - - - - - - - browser.startup.homepage - browser.search.defaultenginename - - - @@ -419,14 +335,6 @@ - - - security.csp.enable - security.fileuri.strict_origin_policy - security.mixed_content.block_active_content - - - @@ -459,10 +367,6 @@ - - - - @@ -491,10 +395,6 @@ - - - - @@ -531,14 +431,6 @@ - - - - - - - - @@ -559,10 +451,6 @@ - - - - @@ -571,14 +459,6 @@ - - - - - - - - browser.search.defaultenginename @@ -603,10 +483,6 @@ - - - - @@ -634,10 +510,6 @@ - - - - @@ -658,14 +530,6 @@ - - - - - - - - @@ -678,10 +542,6 @@ - - - - @@ -704,42 +564,18 @@ - - - - - - - - - - - - - - - - - - - - - - - - @@ -759,26 +595,6 @@ - - - - - - - - - - - - - - - - - - - - @@ -803,18 +619,10 @@ - - - - - - - - browser.startup.homepage @@ -856,15 +664,6 @@ - - - - - - - - - browser.startup.homepage @@ -880,10 +679,6 @@ - - - - browser.startup.homepage @@ -891,18 +686,10 @@ - - - - - - - - @@ -959,10 +746,6 @@ - - - - @@ -975,10 +758,6 @@ - - - - @@ -1039,22 +818,10 @@ - - - - - - - - - - - - @@ -1074,10 +841,6 @@ - - - - @@ -1090,11 +853,11 @@ - + - + - + @@ -1102,10 +865,6 @@ - - - - @@ -1114,10 +873,6 @@ - - - - @@ -1138,13 +893,10 @@ - + - - - - - + + @@ -1169,18 +921,10 @@ - - - - - - - - @@ -1201,17 +945,13 @@ - - - - - + - + @@ -1259,13 +999,14 @@ - + - + + - + - + @@ -1279,23 +1020,10 @@ - - - - - - - - - - - - - @@ -1361,10 +1089,6 @@ - - - - @@ -1373,10 +1097,6 @@ - - - - @@ -1399,10 +1119,6 @@ - - - - @@ -1481,10 +1197,6 @@ - - - - @@ -1528,14 +1240,6 @@ - - - - - - - - @@ -1558,10 +1262,6 @@ - - - - @@ -1626,10 +1326,6 @@ - - - - @@ -1646,10 +1342,6 @@ - - - - @@ -1666,14 +1358,6 @@ - - - - - - - - @@ -1702,18 +1386,10 @@ - - - - - - - - @@ -1778,14 +1454,6 @@ - - - - - - - - @@ -1827,18 +1495,6 @@ - - - - - - - - - - - - @@ -1847,11 +1503,6 @@ - - - - - @@ -1880,22 +1531,6 @@ - - - - - - - - - - - - - - - - @@ -1904,6 +1539,14 @@ + + + + + + + + @@ -1928,10 +1571,6 @@ - - - - @@ -1948,26 +1587,10 @@ - - - - - - - - - - - - - - - - @@ -1988,18 +1611,10 @@ - - - - - - - - @@ -2008,34 +1623,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -2052,22 +1639,6 @@ - - - - - - - - - - - - - - - - @@ -2076,30 +1647,10 @@ - - - - - - - - - - - - - - - - - - - - @@ -2272,13 +1823,13 @@ - + - + - + - + @@ -2304,14 +1855,6 @@ - - - - - - - - @@ -2356,10 +1899,6 @@ - - - - @@ -2476,10 +2015,6 @@ - - - - @@ -2872,10 +2407,6 @@ - - - - @@ -2952,10 +2483,6 @@ - - - - @@ -3057,10 +2584,6 @@ - - - - @@ -3169,10 +2692,6 @@ - - - - @@ -3289,10 +2808,6 @@ - - - - @@ -3585,7 +3100,343 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3621,15 +3472,15 @@ https://get.adobe.com/shockwave/ - - - https://get.adobe.com/flashplayer/ - - https://get.adobe.com/flashplayer/ - + + + + + https://get.adobe.com/flashplayer/ + diff -Nru thunderbird-68.3.0/browser/components/customizableui/test/browser_exit_background_customize_mode.js thunderbird-68.4.1/browser/components/customizableui/test/browser_exit_background_customize_mode.js --- thunderbird-68.3.0/browser/components/customizableui/test/browser_exit_background_customize_mode.js 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/customizableui/test/browser_exit_background_customize_mode.js 2020-01-09 03:28:21.000000000 +0000 @@ -26,8 +26,9 @@ await BrowserTestUtils.switchTab(gBrowser, nonCustomizingTab); await finishedCustomizing; - BrowserTestUtils.loadURI(custTab.linkedBrowser, "http://example.com"); - await BrowserTestUtils.browserLoaded(custTab.linkedBrowser); + let newURL = "http://example.com/"; + BrowserTestUtils.loadURI(custTab.linkedBrowser, newURL); + await BrowserTestUtils.browserLoaded(custTab.linkedBrowser, false, newURL); Assert.equal( gBrowser.tabContainer.querySelector("tab[customizemode=true]"), diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/Policies.jsm thunderbird-68.4.1/browser/components/enterprisepolicies/Policies.jsm --- thunderbird-68.3.0/browser/components/enterprisepolicies/Policies.jsm 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/Policies.jsm 2020-01-09 03:28:21.000000000 +0000 @@ -738,11 +738,16 @@ blockAllExtensions = true; // Turn off discovery pane in about:addons setAndLockPref("extensions.getAddons.showPane", false); + // Turn off recommendations + setAndLockPref( + "extensions.htmlaboutaddons.recommendations.enable", + false + ); // Block about:debugging blockAboutPage(manager, "about:debugging"); } } - let { addons } = await AddonManager.getActiveAddons(); + let addons = await AddonManager.getAllAddons(); let allowedExtensions = []; for (let extensionID in extensionSettings) { if (extensionID == "*") { diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/helpers/BookmarksPolicies.jsm thunderbird-68.4.1/browser/components/enterprisepolicies/helpers/BookmarksPolicies.jsm --- thunderbird-68.3.0/browser/components/enterprisepolicies/helpers/BookmarksPolicies.jsm 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/helpers/BookmarksPolicies.jsm 2020-01-09 03:28:21.000000000 +0000 @@ -206,13 +206,11 @@ }); if (bookmark.Favicon) { - await setFaviconForBookmark(bookmark).catch(() => - log.error(`Error setting favicon for ${bookmark.Title}`) - ); + setFaviconForBookmark(bookmark); } } -async function setFaviconForBookmark(bookmark) { +function setFaviconForBookmark(bookmark) { let faviconURI; let nullPrincipal = Services.scriptSecurityManager.createNullPrincipal({}); @@ -238,19 +236,17 @@ default: log.error(`Bad URL given for favicon on bookmark "${bookmark.Title}"`); - return Promise.resolve(); + return; } - return new Promise(resolve => { - PlacesUtils.favicons.setAndFetchFaviconForPage( - Services.io.newURI(bookmark.URL.href), - faviconURI, - false /* forceReload */, - PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, - resolve, - nullPrincipal - ); - }); + PlacesUtils.favicons.setAndFetchFaviconForPage( + Services.io.newURI(bookmark.URL.href), + faviconURI, + false /* forceReload */, + PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, + null, + nullPrincipal + ); } // Cache of folder names to guids to be used by the getParentGuid diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/schemas/policies-schema.json thunderbird-68.4.1/browser/components/enterprisepolicies/schemas/policies-schema.json --- thunderbird-68.3.0/browser/components/enterprisepolicies/schemas/policies-schema.json 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/schemas/policies-schema.json 2020-01-09 03:28:21.000000000 +0000 @@ -718,6 +718,9 @@ "browser.fixup.dns_first_for_single_words": { "type": "boolean" }, + "browser.newtabpage.activity-stream.default.sites": { + "type": "string" + }, "browser.safebrowsing.phishing.enabled": { "type": "boolean" }, @@ -775,6 +778,9 @@ "extensions.getAddons.showPane": { "type": "boolean" }, + "extensions.htmlaboutaddons.recommendations.enabled": { + "type": "boolean" + }, "geo.enabled": { "type": "boolean" }, @@ -790,6 +796,12 @@ "media.gmp-widevinecdm.enabled": { "type": "boolean" }, + "media.peerconnection.enabled": { + "type": "boolean" + }, + "media.peerconnection.ice.obfuscate_host_addresses.whitelist": { + "type": "string" + }, "network.dns.disableIPv6": { "type": "boolean" }, @@ -808,14 +820,23 @@ "security.default_personal_cert": { "type": "string" }, + "security.mixed_content.block_active_content": { + "type": "boolean" + }, + "security.osclientcerts.autoload": { + "type": "boolean" + }, "security.ssl.errorReporting.enabled": { "type": "boolean" }, - "security.mixed_content.block_active_content": { + "security.tls.hello_downgrade_check": { "type": "boolean" }, "ui.key.menuAccessKeyFocuses": { "type": "boolean" + }, + "widget.content.gtk-theme-override": { + "type": "string" } } }, diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/tests/browser/404.sjs thunderbird-68.4.1/browser/components/enterprisepolicies/tests/browser/404.sjs --- thunderbird-68.3.0/browser/components/enterprisepolicies/tests/browser/404.sjs 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/tests/browser/404.sjs 2020-01-09 03:28:21.000000000 +0000 @@ -0,0 +1,3 @@ +function handleRequest(request, response) { + response.setStatusLine(request.httpVersion, 404, "Not Found"); +} diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/tests/browser/browser.ini thunderbird-68.4.1/browser/components/enterprisepolicies/tests/browser/browser.ini --- thunderbird-68.3.0/browser/components/enterprisepolicies/tests/browser/browser.ini 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/tests/browser/browser.ini 2020-01-09 03:28:21.000000000 +0000 @@ -10,6 +10,7 @@ ../../../../../toolkit/components/antitracking/test/browser/page.html ../../../../../toolkit/components/antitracking/test/browser/subResources.sjs extensionsettings.html + 404.sjs [browser_policies_getActivePolicies.js] skip-if = os != 'mac' diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/tests/browser/browser_policies_notice_in_aboutpreferences.js thunderbird-68.4.1/browser/components/enterprisepolicies/tests/browser/browser_policies_notice_in_aboutpreferences.js --- thunderbird-68.3.0/browser/components/enterprisepolicies/tests/browser/browser_policies_notice_in_aboutpreferences.js 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/tests/browser/browser_policies_notice_in_aboutpreferences.js 2020-01-09 03:28:21.000000000 +0000 @@ -5,7 +5,9 @@ add_task(async function test_notice_in_aboutprefences() { await setupPolicyEngineWithJson({ - policies: {}, + policies: { + DummyPolicy: true, + }, }); await BrowserTestUtils.withNewTab("about:preferences", async browser => { diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/tests/xpcshell/test_empty_policy.js thunderbird-68.4.1/browser/components/enterprisepolicies/tests/xpcshell/test_empty_policy.js --- thunderbird-68.3.0/browser/components/enterprisepolicies/tests/xpcshell/test_empty_policy.js 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/tests/xpcshell/test_empty_policy.js 2020-01-09 03:28:21.000000000 +0000 @@ -0,0 +1,32 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +add_task(async function test_empty_policy() { + await setupPolicyEngineWithJson({ + policies: { + Certificates: {}, + }, + }); + + equal( + Services.policies.status, + Ci.nsIEnterprisePolicies.INACTIVE, + "Engine is not active" + ); +}); + +add_task(async function test_empty_array() { + await setupPolicyEngineWithJson({ + policies: { + RequestedLocales: [], + }, + }); + + equal( + Services.policies.status, + Ci.nsIEnterprisePolicies.ACTIVE, + "Engine is active" + ); +}); diff -Nru thunderbird-68.3.0/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini thunderbird-68.4.1/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini --- thunderbird-68.3.0/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/enterprisepolicies/tests/xpcshell/xpcshell.ini 2020-01-09 03:28:21.000000000 +0000 @@ -8,6 +8,7 @@ [test_appupdateurl.js] [test_clear_blocked_cookies.js] [test_defaultbrowsercheck.js] +[test_empty_policy.js] [test_extensions.js] [test_extensionsettings.js] [test_macosparser_unflatten.js] diff -Nru thunderbird-68.3.0/browser/components/originattributes/test/browser/browser.ini thunderbird-68.4.1/browser/components/originattributes/test/browser/browser.ini --- thunderbird-68.3.0/browser/components/originattributes/test/browser/browser.ini 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/originattributes/test/browser/browser.ini 2020-01-09 03:28:21.000000000 +0000 @@ -87,5 +87,5 @@ [browser_permissions.js] [browser_postMessage.js] [browser_sanitize.js] -skip-if = (os == 'win') #Bug 1544810 +skip-if = (os == 'win') || (os == "mac" && os_version == "10.14") || (os == "linux" && bits == 64) #Bug 1544810 [browser_windowOpenerRestriction.js] diff -Nru thunderbird-68.3.0/browser/components/search/SearchTelemetry.jsm thunderbird-68.4.1/browser/components/search/SearchTelemetry.jsm --- thunderbird-68.3.0/browser/components/search/SearchTelemetry.jsm 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/search/SearchTelemetry.jsm 2020-01-09 03:28:21.000000000 +0000 @@ -25,7 +25,8 @@ * - {} name * Details for a particular provider with the string name. * - {regexp} .regexp - * The regular expression used to match the url for the search providers main page. + * The regular expression used to match the url for the search providers + * main page. * - {string} .queryParam * The query parameter name that indicates a search has been made. * - {string} [.codeParam] @@ -33,11 +34,29 @@ * - {array} [.codePrefixes] * An array of the possible string prefixes for a codeParam, indicating a * partner search. - * - {array} [.followOnParams] + * - {array} [.followonParams] * An array of parameters name that indicates this is a follow-on search. * - {array} [.extraAdServersRegexps] * An array of regular expressions used to determine if a link on a search - * page mightbe an advert. + * page might be an advert. + * - {array} [.followonCookies] + * An array of cookie details, which should look like: + * - {string} [extraCodeParam] + * The query parameter name that indicates an extra search provider's + * code. + * - {array} [.extraCodePrefixes] + * An array of the possible string prefixes for a codeParam, indicating + * a partner search. + * - {string} host + * Host name to which the cookie is linked to. + * - {string} name + * Name of the cookie to look for that should contain the search + * provider's code. + * - {string} codeParam + * The cookie parameter name that indicates a search provider's code. + * - {array} .codePrefixes + * An array of the possible string prefixes for a codeParam, indicating + * a partner search. */ const SEARCH_PROVIDER_INFO = { google: { @@ -47,7 +66,7 @@ codePrefixes: ["firefox"], followonParams: ["oq", "ved", "ei"], extraAdServersRegexps: [ - /^https:\/\/www\.googleadservices\.com\/(?:pagead\/)?aclk/, + /^https:\/\/www\.google(?:adservices)?\.com\/(?:pagead\/)?aclk/, ], }, duckduckgo: { @@ -72,6 +91,16 @@ queryParam: "q", codeParam: "pc", codePrefixes: ["MOZ", "MZ"], + followonCookies: [ + { + extraCodeParam: "form", + extraCodePrefixes: ["QBRE"], + host: "www.bing.com", + name: "SRCHS", + codeParam: "PC", + codePrefixes: ["MOZ", "MZ"], + }, + ], }, }; @@ -371,28 +400,40 @@ } else { type = "sap"; } - } else if (provider == "bing") { - // Bing requires lots of extra work related to cookies. - let secondaryCode = queries.get("form"); - // This code is used for all Bing follow-on searches. - if (secondaryCode == "QBRE") { + } else if (searchProviderInfo.followonCookies) { + // Especially Bing requires lots of extra work related to cookies. + for (let followonCookie of searchProviderInfo.followonCookies) { + if (followonCookie.extraCodeParam) { + let eCode = queries.get(followonCookie.extraCodeParam); + if ( + !eCode || + !followonCookie.extraCodePrefixes.some(p => eCode.startsWith(p)) + ) { + continue; + } + } + + // If this cookie is present, it's probably an SAP follow-on. + // This might be an organic follow-on in the same session, but there + // is no way to tell the difference. for (let cookie of Services.cookies.getCookiesFromHost( - "www.bing.com", + followonCookie.host, {} )) { - if (cookie.name == "SRCHS") { - // If this cookie is present, it's probably an SAP follow-on. - // This might be an organic follow-on in the same session, - // but there is no way to tell the difference. - if ( - searchProviderInfo.codePrefixes.some(p => - cookie.value.startsWith("PC=" + p) - ) - ) { - type = "sap-follow-on"; - code = cookie.value.split("=")[1]; - break; - } + if (cookie.name != followonCookie.name) { + continue; + } + + let [cookieParam, cookieValue] = cookie.value + .split("=") + .map(p => p.trim()); + if ( + cookieParam == followonCookie.codeParam && + followonCookie.codePrefixes.some(p => cookieValue.startsWith(p)) + ) { + type = "sap-follow-on"; + code = cookieValue; + break; } } } @@ -417,7 +458,7 @@ SEARCH_COUNTS_HISTOGRAM_KEY ); histogram.add(payload); - LOG(`SearchTelemetry: ${payload} for ${url}`); + LOG(`${payload} for ${url}`); } /** @@ -484,7 +525,7 @@ */ receiveMessage(msg) { if (msg.name != "SearchTelemetry:PageInfo") { - LOG(`"Received unexpected message: ${msg.name}`); + LOG("Received unexpected message: " + msg.name); return; } @@ -506,22 +547,19 @@ * from a search provider page was followed, and if then if that link was an * ad click or not. * - * @param {nsISupports} httpChannel The channel that generated the activity. - * @param {number} activityType The type of activity. - * @param {number} activitySubtype The subtype for the activity. - * @param {PRTime} timestamp The time of the activity. - * @param {number} [extraSizeData] Any size data available for the activity. - * @param {string} [extraStringData] Any extra string data available for the - * activity. + * @param {nsIChannel} nativeChannel The channel that generated the activity. + * @param {number} activityType The type of activity. + * @param {number} activitySubtype The subtype for the activity. */ observeActivity( - httpChannel, + nativeChannel, activityType, - activitySubtype, + activitySubtype /*, timestamp, extraSizeData, - extraStringData + extraStringData*/ ) { + // NOTE: the channel handling code here is inspired by WebRequest.jsm. if ( !this._browserInfoByUrl.size || activityType != @@ -532,37 +570,48 @@ return; } - let channel = httpChannel.QueryInterface(Ci.nsIHttpChannel); - let loadInfo; - try { - loadInfo = channel.loadInfo; - } catch (e) { - // Channels without a loadInfo are not pertinent. + // Sometimes we get a NullHttpChannel, which implements nsIHttpChannel but + // not nsIChannel. + if (!(nativeChannel instanceof Ci.nsIChannel)) { + return; + } + let channel = ChannelWrapper.get(nativeChannel); + // The wrapper is consistent across redirects, so we can use it to track state. + if (channel._adClickRecorded) { + LOG("Ad click already recorded"); return; } - try { - let uri = channel.URI; - let triggerURI = loadInfo.triggeringPrincipal.URI; + // Make a trip through the event loop to make sure statuses have a chance to + // be processed before we get all the info. + Services.tm.dispatchToMainThread(() => { + // We suspect that No Content (204) responses are used to transfer or + // update beacons. They lead to use double-counting ad-clicks, so let's + // ignore them. + if (channel.statusCode == 204) { + LOG("Ignoring activity from ambiguous responses"); + return; + } - if (!triggerURI || !this._browserInfoByUrl.has(triggerURI.spec)) { + let originURL = channel.originURI && channel.originURI.spec; + if (!originURL || !this._browserInfoByUrl.has(originURL)) { return; } - let info = this._getProviderInfoForUrl(uri.spec, true); + let URL = channel.finalURL; + let info = this._getProviderInfoForUrl(URL, true); if (!info) { return; } - Services.telemetry.keyedScalarAdd(SEARCH_AD_CLICKS_SCALAR, info[0], 1); - LOG( - `SearchTelemetry: Counting ad click in page for ${info[0]} ${ - triggerURI.spec - }` - ); - } catch (e) { - Cu.reportError(e); - } + try { + Services.telemetry.keyedScalarAdd(SEARCH_AD_CLICKS_SCALAR, info[0], 1); + channel._adClickRecorded = true; + LOG(`Counting ad click in page for ${info[0]} ${originURL} ${URL}`); + } catch (e) { + Cu.reportError(e); + } + }); } /** @@ -595,7 +644,7 @@ _reportPageWithAds(info) { let item = this._browserInfoByUrl.get(info.url); if (!item) { - LOG(`Expected to report URI with ads but couldn't find the information`); + LOG("Expected to report URI with ads but couldn't find the information"); return; } @@ -604,11 +653,7 @@ item.info.provider, 1 ); - LOG( - `SearchTelemetry: Counting ads in page for ${item.info.provider} ${ - info.url - }` - ); + LOG(`Counting ads in page for ${item.info.provider} ${info.url}`); } } diff -Nru thunderbird-68.3.0/browser/components/search/test/unit/test_urlTelemetry.js thunderbird-68.4.1/browser/components/search/test/unit/test_urlTelemetry.js --- thunderbird-68.3.0/browser/components/search/test/unit/test_urlTelemetry.js 2019-12-01 14:29:17.000000000 +0000 +++ thunderbird-68.4.1/browser/components/search/test/unit/test_urlTelemetry.js 2020-01-09 03:28:21.000000000 +0000 @@ -1,166 +1,203 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); const { SearchTelemetry } = ChromeUtils.import( "resource:///modules/SearchTelemetry.jsm" ); +const { TelemetryTestUtils } = ChromeUtils.import( + "resource://testing-common/TelemetryTestUtils.jsm" +); -add_task(async function test_parsing_search_urls() { - let hs; - // Google search access point. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.google.com/search?q=test&ie=utf-8&oe=utf-8&client=firefox-b-1-ab" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "google.in-content:sap:firefox-b-1-ab" in hs, - "The histogram must contain the correct key" - ); - - // Google search access point follow-on. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.google.com/search?client=firefox-b-1-ab&ei=EI_VALUE&q=test2&oq=test2&gs_l=GS_L_VALUE" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "google.in-content:sap-follow-on:firefox-b-1-ab" in hs, - "The histogram must contain the correct key" - ); - - // Google organic. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.google.com/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "google.in-content:organic:none" in hs, - "The histogram must contain the correct key" - ); - - // Google organic UK. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.google.co.uk/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "google.in-content:organic:none" in hs, - "The histogram must contain the correct key" - ); - - // Yahoo organic. - SearchTelemetry.updateTrackingStatus( - {}, - "https://search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "yahoo.in-content:organic:none" in hs, - "The histogram must contain the correct key" - ); - - // Yahoo organic UK. - SearchTelemetry.updateTrackingStatus( - {}, - "https://uk.search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "yahoo.in-content:organic:none" in hs, - "The histogram must contain the correct key" - ); - - // Bing search access point. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.bing.com/search?q=test&pc=MOZI&form=MOZLBR" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "bing.in-content:sap:MOZI" in hs, - "The histogram must contain the correct key" - ); - - // Bing organic. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.bing.com/search?q=test&qs=n&form=QBLH&sp=-1&pq=&sc=0-0&sk=&cvid=CVID_VALUE" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "bing.in-content:organic:none" in hs, - "The histogram must contain the correct key" - ); - - // DuckDuckGo search access point. - SearchTelemetry.updateTrackingStatus( - {}, - "https://duckduckgo.com/?q=test&t=ffab" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "duckduckgo.in-content:sap:ffab" in hs, - "The histogram must contain the correct key" - ); - - // DuckDuckGo organic. - SearchTelemetry.updateTrackingStatus( - {}, - "https://duckduckgo.com/?q=test&t=hi&ia=news" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "duckduckgo.in-content:organic:hi" in hs, - "The histogram must contain the correct key" - ); - - // Baidu search access point. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.baidu.com/baidu?wd=test&tn=monline_7_dg&ie=utf-8" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "baidu.in-content:sap:monline_7_dg" in hs, - "The histogram must contain the correct key" - ); - - // Baidu search access point follow-on. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=monline_7_dg&wd=test2&oq=test&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn&rsv_enter=1&rsv_sug3=2&rsv_sug2=0&inputT=227&rsv_sug4=397" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "baidu.in-content:sap-follow-on:monline_7_dg" in hs, - "The histogram must contain the correct key" - ); +const TESTS = [ + { + title: "Google search access point", + trackingUrl: + "https://www.google.com/search?q=test&ie=utf-8&oe=utf-8&client=firefox-b-1-ab", + expectedSearchCountEntry: "google.in-content:sap:firefox-b-1-ab", + expectedAdKey: "google", + adUrls: [ + "https://www.googleadservices.com/aclk=foobar", + "https://www.googleadservices.com/pagead/aclk=foobar", + "https://www.google.com/aclk=foobar", + "https://www.google.com/pagead/aclk=foobar", + ], + nonAdUrls: [ + "https://www.googleadservices.com/?aclk=foobar", + "https://www.googleadservices.com/bar", + "https://www.google.com/image", + ], + }, + { + title: "Google search access point follow-on", + trackingUrl: + "https://www.google.com/search?client=firefox-b-1-ab&ei=EI_VALUE&q=test2&oq=test2&gs_l=GS_L_VALUE", + expectedSearchCountEntry: "google.in-content:sap-follow-on:firefox-b-1-ab", + }, + { + title: "Google organic", + trackingUrl: + "https://www.google.com/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE", + expectedSearchCountEntry: "google.in-content:organic:none", + }, + { + title: "Google organic UK", + trackingUrl: + "https://www.google.co.uk/search?source=hp&ei=EI_VALUE&q=test&oq=test&gs_l=GS_L_VALUE", + expectedSearchCountEntry: "google.in-content:organic:none", + }, + { + title: "Yahoo organic", + trackingUrl: + "https://search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8", + expectedSearchCountEntry: "yahoo.in-content:organic:none", + }, + { + title: "Yahoo organic UK", + trackingUrl: + "https://uk.search.yahoo.com/search?p=test&fr=yfp-t&fp=1&toggle=1&cop=mss&ei=UTF-8", + expectedSearchCountEntry: "yahoo.in-content:organic:none", + }, + { + title: "Bing search access point", + trackingUrl: "https://www.bing.com/search?q=test&pc=MOZI&form=MOZLBR", + expectedSearchCountEntry: "bing.in-content:sap:MOZI", + }, + { + setUp() { + Services.cookies.removeAll(); + Services.cookies.add( + "www.bing.com", + "/", + "SRCHS", + "PC=MOZ", + false, + false, + false, + Date.now() + 1000 * 60 * 60, + {}, + Ci.nsICookie.SAMESITE_NONE + ); + }, + tearDown() { + Services.cookies.removeAll(); + }, + title: "Bing search access point follow-on", + trackingUrl: + "https://www.bing.com/search?q=test&qs=n&form=QBRE&sp=-1&pq=&sc=0-0&sk=&cvid=CVID_VALUE", + expectedSearchCountEntry: "bing.in-content:sap-follow-on:MOZ", + }, + { + title: "Bing organic", + trackingUrl: + "https://www.bing.com/search?q=test&qs=n&form=QBLH&sp=-1&pq=&sc=0-0&sk=&cvid=CVID_VALUE", + expectedSearchCountEntry: "bing.in-content:organic:none", + }, + { + title: "DuckDuckGo search access point", + trackingUrl: "https://duckduckgo.com/?q=test&t=ffab", + expectedSearchCountEntry: "duckduckgo.in-content:sap:ffab", + }, + { + title: "DuckDuckGo organic", + trackingUrl: "https://duckduckgo.com/?q=test&t=hi&ia=news", + expectedSearchCountEntry: "duckduckgo.in-content:organic:hi", + }, + { + title: "Baidu search access point", + trackingUrl: "https://www.baidu.com/baidu?wd=test&tn=monline_7_dg&ie=utf-8", + expectedSearchCountEntry: "baidu.in-content:sap:monline_7_dg", + }, + { + title: "Baidu search access point follow-on", + trackingUrl: + "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=monline_7_dg&wd=test2&oq=test&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn&rsv_enter=1&rsv_sug3=2&rsv_sug2=0&inputT=227&rsv_sug4=397", + expectedSearchCountEntry: "baidu.in-content:sap-follow-on:monline_7_dg", + }, + { + title: "Baidu organic", + trackingUrl: + "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=&tn=baidu&bar=&wd=test&rn=&oq=&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn", + expectedSearchCountEntry: "baidu.in-content:organic:baidu", + }, +]; + +/** + * This function is primarily for testing the Ad URL regexps that are triggered + * when a URL is clicked on. These regexps are also used for the `with_ads` + * probe. However, we test the ad_clicks route as that is easier to hit. + * + * @param {string} serpUrl + * The url to simulate where the page the click came from. + * @param {string} adUrl + * The ad url to simulate being clicked. + * @param {string} [expectedAdKey] + * The expected key to be logged for the scalar. Omit if no scalar should be + * logged. + */ +async function testAdUrlClicked(serpUrl, adUrl, expectedAdKey) { + info(`Testing Ad URL: ${adUrl}`); + let channel = NetUtil.newChannel({ + uri: NetUtil.newURI(adUrl), + triggeringPrincipal: Services.scriptSecurityManager.createCodebasePrincipal( + NetUtil.newURI(serpUrl), + {} + ), + loadUsingSystemPrincipal: true, + }); + SearchTelemetry._contentHandler.observeActivity( + channel, + Ci.nsIHttpActivityObserver.ACTIVITY_TYPE_HTTP_TRANSACTION, + Ci.nsIHttpActivityObserver.ACTIVITY_SUBTYPE_TRANSACTION_CLOSE + ); + // Since the content handler takes a moment to allow the channel information + // to settle down, wait the same amount of time here. + await new Promise(resolve => Services.tm.dispatchToMainThread(resolve)); + + const scalars = TelemetryTestUtils.getProcessScalars("parent", true, true); + if (!expectedAdKey) { + Assert.ok( + !("browser.search.ad_clicks" in scalars), + "Should not have recorded an ad click" + ); + } else { + TelemetryTestUtils.assertKeyedScalar( + scalars, + "browser.search.ad_clicks", + expectedAdKey, + 1 + ); + } +} - // Baidu organic. - SearchTelemetry.updateTrackingStatus( - {}, - "https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&ch=&tn=baidu&bar=&wd=test&rn=&oq=&rsv_pq=RSV_PQ_VALUE&rsv_t=RSV_T_VALUE&rqlang=cn" - ); - hs = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS").snapshot(); - Assert.ok(hs); - Assert.ok( - "baidu.in-content:organic:baidu" in hs, - "The histogram must contain the correct key" - ); +add_task(async function test_parsing_search_urls() { + for (const test of TESTS) { + info(`Running ${test.title}`); + if (test.setUp) { + test.setUp(); + } + SearchTelemetry.updateTrackingStatus({}, test.trackingUrl); + const hs = Services.telemetry + .getKeyedHistogramById("SEARCH_COUNTS") + .snapshot(); + Assert.ok(hs); + Assert.ok( + test.expectedSearchCountEntry in hs, + "The histogram must contain the correct key" + ); + + if ("adUrls" in test) { + for (const adUrl of test.adUrls) { + await testAdUrlClicked(test.trackingUrl, adUrl, test.expectedAdKey); + } + for (const nonAdUrls of test.nonAdUrls) { + await testAdUrlClicked(test.trackingUrl, nonAdUrls); + } + } + + if (test.tearDown) { + test.tearDown(); + } + } }); diff -Nru thunderbird-68.3.0/browser/components/sessionstore/test/browser_duplicate_history.js thunderbird-68.4.1/browser/components/sessionstore/test/browser_duplicate_history.js --- thunderbird-68.3.0/browser/components/sessionstore/test/browser_duplicate_history.js 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/browser/components/sessionstore/test/browser_duplicate_history.js 2020-01-09 03:28:21.000000000 +0000 @@ -23,7 +23,10 @@ let before = TabStateCache.get(aBrowser); let newTab = SessionStore.duplicateTab(window, tab); - await BrowserTestUtils.browserLoaded(newTab.linkedBrowser); + await Promise.all([ + BrowserTestUtils.browserLoaded(newTab.linkedBrowser), + TestUtils.topicObserved("sessionstore-debug-tab-restored"), + ]); let after = TabStateCache.get(newTab.linkedBrowser); isnot( diff -Nru thunderbird-68.3.0/browser/config/version.txt thunderbird-68.4.1/browser/config/version.txt --- thunderbird-68.3.0/browser/config/version.txt 2019-12-01 14:29:17.000000000 +0000 +++ thunderbird-68.4.1/browser/config/version.txt 2020-01-09 03:28:21.000000000 +0000 @@ -1 +1 @@ -68.3.0 +68.4.1 diff -Nru thunderbird-68.3.0/browser/config/version_display.txt thunderbird-68.4.1/browser/config/version_display.txt --- thunderbird-68.3.0/browser/config/version_display.txt 2019-12-01 14:29:17.000000000 +0000 +++ thunderbird-68.4.1/browser/config/version_display.txt 2020-01-09 03:28:21.000000000 +0000 @@ -1 +1 @@ -68.3.0esr +68.4.1esr diff -Nru thunderbird-68.3.0/build/moz.configure/toolchain.configure thunderbird-68.4.1/build/moz.configure/toolchain.configure --- thunderbird-68.3.0/build/moz.configure/toolchain.configure 2019-12-01 14:29:16.000000000 +0000 +++ thunderbird-68.4.1/build/moz.configure/toolchain.configure 2020-01-09 03:28:21.000000000 +0000 @@ -1652,6 +1652,7 @@ '--enable-optimize', c_compiler, target) def security_hardening_cflags(hardening_flag, asan, optimize, c_compiler, target): compiler_is_gccish = c_compiler.type in ('gcc', 'clang') + mingw_clang = c_compiler.type == 'clang' and target.os == 'WINNT' flags = [] ldflags = [] @@ -1671,17 +1672,19 @@ flags.append("-D_FORTIFY_SOURCE=2") js_flags.append("-U_FORTIFY_SOURCE") js_flags.append("-D_FORTIFY_SOURCE=2") + if mingw_clang: + # mingw-clang needs to link in ssp which is not done by default + ldflags.append('-lssp') + js_ldflags.append('-lssp') # fstack-protector ------------------------------------ # Enable only if hardening is not disabled and ASAN is # not on as ASAN will catch the crashes for us if compiler_is_gccish and not asan: - # mingw-clang cross-compile toolchain has bugs with stack protector - if target.os != 'WINNT' or c_compiler == 'gcc': - flags.append("-fstack-protector-strong") - ldflags.append("-fstack-protector-strong") - js_flags.append("-fstack-protector-strong") - js_ldflags.append("-fstack-protector-strong") + flags.append("-fstack-protector-strong") + ldflags.append("-fstack-protector-strong") + js_flags.append("-fstack-protector-strong") + js_ldflags.append("-fstack-protector-strong") # ASLR ------------------------------------------------ # ASLR (dynamicbase) is enabled by default in clang-cl; but the diff -Nru thunderbird-68.3.0/comm/.gecko_rev.yml thunderbird-68.4.1/comm/.gecko_rev.yml --- thunderbird-68.3.0/comm/.gecko_rev.yml 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/.gecko_rev.yml 2020-01-09 03:30:22.000000000 +0000 @@ -2,7 +2,7 @@ GECKO_BASE_REPOSITORY: https://hg.mozilla.org/mozilla-unified GECKO_HEAD_REPOSITORY: https://hg.mozilla.org/releases/mozilla-esr68 GECKO_HEAD_REF: THUNDERBIRD_68_VERBRANCH -GECKO_HEAD_REV: 78ab5e054eb0a2a71f3d1f1875de5fc4c575ac91 +GECKO_HEAD_REV: 5c3329fb2b7d52fa06d00b6b1b384b0ef7c4a279 ### For comm-central # GECKO_BASE_REPOSITORY: https://hg.mozilla.org/mozilla-unified diff -Nru thunderbird-68.3.0/comm/calendar/base/content/calendar-month-base-view.js thunderbird-68.4.1/comm/calendar/base/content/calendar-month-base-view.js --- thunderbird-68.3.0/comm/calendar/base/content/calendar-month-base-view.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/calendar/base/content/calendar-month-base-view.js 2020-01-09 03:30:22.000000000 +0000 @@ -679,12 +679,11 @@ finishDate.day++; } - if (!targetDate.isDate) { - // Reset the time to 00:00, so that we really get all the boxes. - targetDate.hour = 0; - targetDate.minute = 0; - targetDate.second = 0; - } + // Reset the time to 00:00, so that we really get all the boxes. + targetDate.isDate = false; + targetDate.hour = 0; + targetDate.minute = 0; + targetDate.second = 0; if (targetDate.compare(finishDate) == 0) { // We have also to handle zero length events in particular for diff -Nru thunderbird-68.3.0/comm/calendar/base/content/calendar-multiday-base-view.js thunderbird-68.4.1/comm/calendar/base/content/calendar-multiday-base-view.js --- thunderbird-68.3.0/comm/calendar/base/content/calendar-multiday-base-view.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/calendar/base/content/calendar-multiday-base-view.js 2020-01-09 03:30:22.000000000 +0000 @@ -1415,12 +1415,11 @@ finishDate.day++; } - if (!targetDate.isDate) { - // Set the time to 00:00 so that we get all the boxes. - targetDate.hour = 0; - targetDate.minute = 0; - targetDate.second = 0; - } + // Set the time to 00:00 so that we get all the boxes. + targetDate.isDate = false; + targetDate.hour = 0; + targetDate.minute = 0; + targetDate.second = 0; if (targetDate.compare(finishDate) == 0) { // We have also to handle zero length events in particular for diff -Nru thunderbird-68.3.0/comm/calendar/base/themes/common/calendar-task-tree.css thunderbird-68.4.1/comm/calendar/base/themes/common/calendar-task-tree.css --- thunderbird-68.3.0/comm/calendar/base/themes/common/calendar-task-tree.css 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/calendar/base/themes/common/calendar-task-tree.css 2020-01-09 03:30:22.000000000 +0000 @@ -42,6 +42,10 @@ font-style: italic; } +.calendar-task-tree > treechildren::-moz-tree-cell-text(duetoday) { + font-weight: bold; +} + .calendar-task-tree-col-priority { list-style-image: url(chrome://calendar-common/skin/icons/priority.svg); -moz-context-properties: fill; diff -Nru thunderbird-68.3.0/comm/calendar/base/themes/common/dialogs/calendar-event-dialog.css thunderbird-68.4.1/comm/calendar/base/themes/common/dialogs/calendar-event-dialog.css --- thunderbird-68.3.0/comm/calendar/base/themes/common/dialogs/calendar-event-dialog.css 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/calendar/base/themes/common/dialogs/calendar-event-dialog.css 2020-01-09 03:30:22.000000000 +0000 @@ -4,7 +4,7 @@ dialog { --eventBorderColor: #8d8e90; - --eventWidgetBorderColor: #cacaff; + --eventWidgetBorderColor: #aaaabc; --eventGridStartBorderColor: #bdbec0; } @@ -348,7 +348,8 @@ -moz-appearance: none; margin: 0px 0px; border: 1px solid var(--eventBorderColor); - background-color: #fff; + background-color: -moz-Field; + color: -moz-FieldText; } #timebar { @@ -651,6 +652,10 @@ #attendees-list hbox textbox { width: 100%; } +#attendees-list hbox textbox[disabled="true"] { + color: inherit; + opacity: 0.5; +} .selection-bar-left { width: 3px; diff -Nru thunderbird-68.3.0/comm/calendar/base/themes/common/icons/edit.svg thunderbird-68.4.1/comm/calendar/base/themes/common/icons/edit.svg --- thunderbird-68.3.0/comm/calendar/base/themes/common/icons/edit.svg 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/calendar/base/themes/common/icons/edit.svg 2020-01-09 03:30:22.000000000 +0000 @@ -2,5 +2,5 @@ - License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - + diff -Nru thunderbird-68.3.0/comm/calendar/resources/skin/datetimepickers.css thunderbird-68.4.1/comm/calendar/resources/skin/datetimepickers.css --- thunderbird-68.3.0/comm/calendar/resources/skin/datetimepickers.css 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/calendar/resources/skin/datetimepickers.css 2020-01-09 03:30:22.000000000 +0000 @@ -89,16 +89,23 @@ /* Box in each cell of the grid for hours */ -.time-picker-hour-box-class { +.time-picker-hour-grid[format12hours="false"] .time-picker-hour-box-class { + min-width : 28px; + -moz-box-align : center; + border-left : 1px solid ThreeDShadow; +} + +.time-picker-hour-grid[format12hours="true"] .time-picker-hour-box-class { min-width : 24px; -moz-box-align : center; - border-left : 1px solid ThreeDShadow; + border-left : 1px solid ThreeDShadow; } .timepicker-topRow-hour-class { border-bottom : 1px solid ThreeDShadow; } -grid[anonid="time-picker-hour-grid"][format12hours="true"] .timepicker-topRow-hour-class { + +.time-picker-hour-grid[format12hours="true"] .timepicker-topRow-hour-class { border-bottom : 2px solid ThreeDShadow; } @@ -153,14 +160,14 @@ /* box around five minute grid */ -vbox[anonid="time-picker-five-minute-grid-box"] { +.time-picker-five-minute-grid-box { min-width : 195px; margin-inline-start : 1px; } /* five minute grid */ -grid[anonid="time-picker-five-minute-grid"] { +.time-picker-five-minute-grid { margin-top : 2px; margin-inline-end : 1px; border-top : 1px solid ThreeDShadow; @@ -194,15 +201,14 @@ } /* box around one minute grid */ - -vbox[anonid="time-picker-one-minute-grid-box"] { +.time-picker-one-minute-grid-box { min-width : 195px; margin-inline-start : 1px; } /* one minute grid */ -grid[anonid="time-picker-one-minute-grid"] { +.time-picker-one-minute-grid { margin-top : 2px; margin-inline-end : 1px; border-top : 1px solid ThreeDShadow; diff -Nru thunderbird-68.3.0/comm/chat/chat-prefs.js thunderbird-68.4.1/comm/chat/chat-prefs.js --- thunderbird-68.3.0/comm/chat/chat-prefs.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/chat/chat-prefs.js 2020-01-09 03:30:22.000000000 +0000 @@ -88,6 +88,8 @@ pref("chat.prpls.prpl-facebook.disable", true); // Disable experimental Matrix support. pref("chat.prpls.prpl-matrix.disable", true); +// Disable Twitter until support for the updated API is complete. See bug 1445778. +pref("chat.prpls.prpl-twitter.disable", true); // Disable Yahoo Messenger as legacy Yahoo was shut down. pref("chat.prpls.prpl-yahoo.disable", true); // Whether to disable SRV lookups that use the system DNS library. diff -Nru thunderbird-68.3.0/comm/chat/modules/DNS.jsm thunderbird-68.4.1/comm/chat/modules/DNS.jsm --- thunderbird-68.3.0/comm/chat/modules/DNS.jsm 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/chat/modules/DNS.jsm 1970-01-01 00:00:00.000000000 +0000 @@ -1,437 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -// This module is responsible for performing DNS queries using ctypes for -// loading system DNS libraries on Linux, Mac and Windows. - -if (typeof Components !== "undefined") { - var { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm"); - var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); - var { BasePromiseWorker } = ChromeUtils.import( - "resource://gre/modules/PromiseWorker.jsm" - ); -} - -var LOCATION = "resource:///modules/DNS.jsm"; - -// These constants are luckily shared, but with different names -var NS_T_TXT = 16; // DNS_TYPE_TXT -var NS_T_SRV = 33; // DNS_TYPE_SRV - -// For Linux and Mac. -function load_libresolv() { - this._open(); -} - -load_libresolv.prototype = { - library: null, - - // Tries to find and load library. - _open() { - function findLibrary() { - let lastException = null; - let libnames = [ - ctypes.libraryName("resolv.9"), - ctypes.libraryName("resolv"), - ]; - for (let libname of libnames) { - try { - return ctypes.open(libname); - } catch (ex) { - lastException = ex; - } - } - throw new Error( - "Could not find libresolv in any of " + - libnames + - " Exception: " + - lastException + - "\n" - ); - } - - // Declaring functions to be able to call them. - function declare(aSymbolNames, ...aArgs) { - let lastException = null; - if (!Array.isArray(aSymbolNames)) { - aSymbolNames = [aSymbolNames]; - } - - for (let name of aSymbolNames) { - try { - return library.declare(name, ...aArgs); - } catch (ex) { - lastException = ex; - } - } - library.close(); - throw new Error( - "Failed to declare " + - aSymbolNames + - " Exception: " + - lastException + - "\n" - ); - } - - let library = (this.library = findLibrary()); - this.res_search = declare( - ["res_9_search", "res_search", "__res_search"], - ctypes.default_abi, - ctypes.int, - ctypes.char.ptr, - ctypes.int, - ctypes.int, - ctypes.unsigned_char.ptr, - ctypes.int - ); - this.res_query = declare( - ["res_9_query", "res_query", "__res_query"], - ctypes.default_abi, - ctypes.int, - ctypes.char.ptr, - ctypes.int, - ctypes.int, - ctypes.unsigned_char.ptr, - ctypes.int - ); - this.dn_expand = declare( - ["res_9_dn_expand", "dn_expand", "__dn_expand"], - ctypes.default_abi, - ctypes.int, - ctypes.unsigned_char.ptr, - ctypes.unsigned_char.ptr, - ctypes.unsigned_char.ptr, - ctypes.char.ptr, - ctypes.int - ); - this.dn_skipname = declare( - ["res_9_dn_skipname", "dn_skipname", "__dn_skipname"], - ctypes.default_abi, - ctypes.int, - ctypes.unsigned_char.ptr, - ctypes.unsigned_char.ptr - ); - this.ns_get16 = declare( - ["res_9_ns_get16", "ns_get16"], - ctypes.default_abi, - ctypes.unsigned_int, - ctypes.unsigned_char.ptr - ); - this.ns_get32 = declare( - ["res_9_ns_get32", "ns_get32"], - ctypes.default_abi, - ctypes.unsigned_long, - ctypes.unsigned_char.ptr - ); - - this.QUERYBUF_SIZE = 1024; - this.NS_MAXCDNAME = 255; - this.NS_HFIXEDSZ = 12; - this.NS_QFIXEDSZ = 4; - this.NS_RRFIXEDSZ = 10; - this.NS_C_IN = 1; - }, - - close() { - this.library.close(); - this.library = null; - }, - - // Maps record to SRVRecord or TXTRecord according to aTypeID and return it. - _mapAnswer(aTypeID, aAnswer, aIdx, aLength) { - if (aTypeID == NS_T_SRV) { - let prio = this.ns_get16(aAnswer.addressOfElement(aIdx)); - let weight = this.ns_get16(aAnswer.addressOfElement(aIdx + 2)); - let port = this.ns_get16(aAnswer.addressOfElement(aIdx + 4)); - - let hostbuf = ctypes.char.array(this.NS_MAXCDNAME)(); - let hostlen = this.dn_expand( - aAnswer.addressOfElement(0), - aAnswer.addressOfElement(aLength), - aAnswer.addressOfElement(aIdx + 6), - hostbuf, - this.NS_MAXCDNAME - ); - let host = hostlen > -1 ? hostbuf.readString() : null; - return new SRVRecord(prio, weight, host, port); - } else if (aTypeID == NS_T_TXT) { - // TODO should only read dataLength characters. - let data = ctypes.unsigned_char.ptr(aAnswer.addressOfElement(aIdx + 1)); - return new TXTRecord(data.readString()); - } - return {}; - }, - - // Performs a DNS query for aTypeID on a certain address (aName) and returns - // array of records of aTypeID. - lookup(aName, aTypeID) { - let qname = ctypes.char.array()(aName); - let answer = ctypes.unsigned_char.array(this.QUERYBUF_SIZE)(); - let length = this.res_search( - qname, - this.NS_C_IN, - aTypeID, - answer, - this.QUERYBUF_SIZE - ); - - // There is an error. - if (length < 0) { - return -1; - } - - let results = []; - let idx = this.NS_HFIXEDSZ; - - let qdcount = this.ns_get16(answer.addressOfElement(4)); - let ancount = this.ns_get16(answer.addressOfElement(6)); - - for (let qdidx = 0; qdidx < qdcount && idx < length; qdidx++) { - idx += - this.NS_QFIXEDSZ + - this.dn_skipname( - answer.addressOfElement(idx), - answer.addressOfElement(length) - ); - } - - for (let anidx = 0; anidx < ancount && idx < length; anidx++) { - idx += this.dn_skipname( - answer.addressOfElement(idx), - answer.addressOfElement(length) - ); - let rridx = idx; - let type = this.ns_get16(answer.addressOfElement(rridx)); - let dataLength = this.ns_get16(answer.addressOfElement(rridx + 8)); - - idx += this.NS_RRFIXEDSZ; - - if (type === aTypeID) { - let resource = this._mapAnswer(aTypeID, answer, idx, length); - resource.type = type; - resource.nsclass = this.ns_get16(answer.addressOfElement(rridx + 2)); - resource.ttl = this.ns_get32(answer.addressOfElement(rridx + 4)) | 0; - results.push(resource); - } - idx += dataLength; - } - return results; - }, -}; - -// For Windows. -function load_dnsapi() { - this._open(); -} - -load_dnsapi.prototype = { - library: null, - - // Tries to find and load library. - _open() { - function declare(aSymbolName, ...aArgs) { - try { - return library.declare(aSymbolName, ...aArgs); - } catch (ex) { - throw new Error( - "Failed to declare " + aSymbolName + " Exception: " + ex + "\n" - ); - } - } - - let library = (this.library = ctypes.open(ctypes.libraryName("DnsAPI"))); - - this.DNS_SRV_DATA = ctypes.StructType("DNS_SRV_DATA", [ - { pNameTarget: ctypes.jschar.ptr }, - { wPriority: ctypes.unsigned_short }, - { wWeight: ctypes.unsigned_short }, - { wPort: ctypes.unsigned_short }, - { Pad: ctypes.unsigned_short }, - ]); - - this.DNS_TXT_DATA = ctypes.StructType("DNS_TXT_DATA", [ - { dwStringCount: ctypes.unsigned_long }, - { pStringArray: ctypes.jschar.ptr.array(1) }, - ]); - - this.DNS_RECORD = ctypes.StructType("_DnsRecord"); - this.DNS_RECORD.define([ - { pNext: this.DNS_RECORD.ptr }, - { pName: ctypes.jschar.ptr }, - { wType: ctypes.unsigned_short }, - { wDataLength: ctypes.unsigned_short }, - { Flags: ctypes.unsigned_long }, - { dwTtl: ctypes.unsigned_long }, - { dwReserved: ctypes.unsigned_long }, - { Data: this.DNS_SRV_DATA }, // it's a union, can be cast to many things - ]); - - this.PDNS_RECORD = ctypes.PointerType(this.DNS_RECORD); - this.DnsQuery_W = declare( - "DnsQuery_W", - ctypes.winapi_abi, - ctypes.long, - ctypes.jschar.ptr, - ctypes.unsigned_short, - ctypes.unsigned_long, - ctypes.voidptr_t, - this.PDNS_RECORD.ptr, - ctypes.voidptr_t.ptr - ); - this.DnsRecordListFree = declare( - "DnsRecordListFree", - ctypes.winapi_abi, - ctypes.void_t, - this.PDNS_RECORD, - ctypes.int - ); - - this.ERROR_SUCCESS = ctypes.Int64(0); - this.DNS_QUERY_STANDARD = 0; - this.DnsFreeRecordList = 1; - }, - - close() { - this.library.close(); - this.library = null; - }, - - // Maps record to SRVRecord or TXTRecord according to aTypeID and return it. - _mapAnswer(aTypeID, aData) { - if (aTypeID == NS_T_SRV) { - let srvdata = ctypes.cast(aData, this.DNS_SRV_DATA); - return new SRVRecord( - srvdata.wPriority, - srvdata.wWeight, - srvdata.pNameTarget.readString(), - srvdata.wPort - ); - } else if (aTypeID == NS_T_TXT) { - let txtdata = ctypes.cast(aData, this.DNS_TXT_DATA); - if (txtdata.dwStringCount > 0) { - return new TXTRecord(txtdata.pStringArray[0].readString()); - } - } - return {}; - }, - - // Performs a DNS query for aTypeID on a certain address (aName) and returns - // array of records of aTypeID (e.g. SRVRecord or TXTRecord). - lookup(aName, aTypeID) { - let queryResultsSet = this.PDNS_RECORD(); - let qname = ctypes.jschar.array()(aName); - let dnsStatus = this.DnsQuery_W( - qname, - aTypeID, - this.DNS_QUERY_STANDARD, - null, - queryResultsSet.address(), - null - ); - - // There is an error. - if (ctypes.Int64.compare(dnsStatus, this.ERROR_SUCCESS) != 0) { - return -1; - } - - let results = []; - for ( - let presult = queryResultsSet; - presult && !presult.isNull(); - presult = presult.contents.pNext - ) { - let result = presult.contents; - if (result.wType == aTypeID) { - let resource = this._mapAnswer(aTypeID, result.Data); - resource.type = result.wType; - resource.nsclass = 0; - resource.ttl = result.dwTtl | 0; - results.push(resource); - } - } - - this.DnsRecordListFree(queryResultsSet, this.DnsFreeRecordList); - return results; - }, -}; - -// Used to make results of different libraries consistent for SRV queries. -function SRVRecord(aPrio, aWeight, aHost, aPort) { - this.prio = aPrio; - this.weight = aWeight; - this.host = aHost; - this.port = aPort; -} - -// Used to make results of different libraries consistent for TXT queries. -function TXTRecord(aData) { - this.data = aData; -} - -if (typeof Components === "undefined") { - /* eslint-env worker */ - - // We are in a worker, wait for our message then execute the wanted method. - importScripts("resource://gre/modules/workers/require.js"); - let PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js"); - - let worker = new PromiseWorker.AbstractWorker(); - worker.dispatch = function(aMethod, aArgs = []) { - return self[aMethod](...aArgs); - }; - worker.postMessage = function(...aArgs) { - self.postMessage(...aArgs); - }; - worker.close = function() { - self.close(); - }; - self.addEventListener("message", msg => worker.handleMessage(msg)); - - // eslint-disable-next-line no-unused-vars - function execute(aOS, aMethod, aArgs) { - let DNS = aOS == "WINNT" ? new load_dnsapi() : new load_libresolv(); - return DNS[aMethod].apply(DNS, aArgs); - } -} else { - // We are loaded as a JSM, provide the async front that will start the - // worker. - var dns_async_front = { - /** - * Constants for use with the lookup function. - */ - TXT: NS_T_TXT, - SRV: NS_T_SRV, - - /** - * Do an asynchronous DNS lookup. The returned promise resolves with - * one of the Answer objects as defined above, or rejects with the - * error from the worker. - * - * Example: DNS.lookup("_caldavs._tcp.example.com", DNS.SRV) - * - * @param aName The aName to look up. - * @param aTypeID The RR type to look up as a constant. - * @return A promise resolved when completed. - */ - lookup(aName, aTypeID) { - let worker = new BasePromiseWorker(LOCATION); - return worker.post("execute", [ - Services.appinfo.OS, - "lookup", - [...arguments], - ]); - }, - - /** Convenience functions */ - srv(aName) { - return this.lookup(aName, NS_T_SRV); - }, - txt(aName) { - return this.lookup(aName, NS_T_TXT); - }, - }; - this.DNS = dns_async_front; - this.EXPORTED_SYMBOLS = ["DNS"]; -} diff -Nru thunderbird-68.3.0/comm/chat/modules/moz.build thunderbird-68.4.1/comm/chat/modules/moz.build --- thunderbird-68.3.0/comm/chat/modules/moz.build 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/chat/modules/moz.build 2020-01-09 03:30:22.000000000 +0000 @@ -9,7 +9,6 @@ 'ArrayBufferUtils.jsm', 'BigInteger.jsm', 'CLib.jsm', - 'DNS.jsm', 'hiddenWindow.jsm', 'imContentSink.jsm', 'imServices.jsm', diff -Nru thunderbird-68.3.0/comm/ldap/xpcom/src/nsLDAPOperation.cpp thunderbird-68.4.1/comm/ldap/xpcom/src/nsLDAPOperation.cpp --- thunderbird-68.3.0/comm/ldap/xpcom/src/nsLDAPOperation.cpp 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/ldap/xpcom/src/nsLDAPOperation.cpp 2020-01-09 03:30:22.000000000 +0000 @@ -476,6 +476,7 @@ // clean up ldap_controls_free(mServerctls); ldap_controls_free(mClientctls); + if (!mAttrs) return; // The last attr entry is null, so no need to free that. int numAttrs = 0; while (mAttrs[numAttrs]) { diff -Nru thunderbird-68.3.0/comm/mail/base/content/folderPane.js thunderbird-68.4.1/comm/mail/base/content/folderPane.js --- thunderbird-68.3.0/comm/mail/base/content/folderPane.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/base/content/folderPane.js 2020-01-09 03:30:22.000000000 +0000 @@ -2953,7 +2953,12 @@ offlineStore.remove(true); } } - gFolderDisplay.view.close(); + + // We may be rebuilding a folder that is not the displayed one. + let sameFolder = gFolderDisplay.displayedFolder == folder; + if (sameFolder) { + gFolderDisplay.view.close(); + } // Send a notification that we are triggering a database rebuild. MailServices.mfn.notifyItemEvent( @@ -2974,7 +2979,9 @@ folder.ForceDBClosed(); } folder.updateFolder(msgWindow); - gFolderDisplay.show(folder); + if (sameFolder) { + gFolderDisplay.show(folder); + } } window.openDialog( diff -Nru thunderbird-68.3.0/comm/mail/base/content/mailWindowOverlay.js thunderbird-68.4.1/comm/mail/base/content/mailWindowOverlay.js --- thunderbird-68.3.0/comm/mail/base/content/mailWindowOverlay.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/base/content/mailWindowOverlay.js 2020-01-09 03:30:22.000000000 +0000 @@ -1487,11 +1487,24 @@ ) { navDebug("history[" + i + "] = " + historyArray[i] + "\n"); navDebug("history[" + i + "] = " + historyArray[i + 1] + "\n"); - folder = MailUtils.getOrCreateFolder(historyArray[i + 1]); + folder = MailServices.folderLookup.getFolderForURL(historyArray[i + 1]); + if (!folder) { + // Where did the folder go? + continue; + } navDebug( - "folder URI = " + folder.URI + "pretty name " + folder.prettyName + "\n" + "folder URI = " + folder.URI + " pretty name " + folder.prettyName + "\n" ); + var menuText = ""; + var msgHdr = messenger.msgHdrFromURI(historyArray[i]); + var msgSubject = msgHdr.mime2DecodedSubject; + var msgAuthor = msgHdr.mime2DecodedAuthor; + + if (!msgAuthor && !msgSubject) { + // Avoid empty entries in the menu. The message was most likely (re)moved. + continue; + } // If the message was not being displayed via the current folder, prepend // the folder name. We do not need to check underlying folders for @@ -1501,20 +1514,18 @@ menuText = folder.prettyName + " - "; } - var msgHdr = messenger.msgHdrFromURI(historyArray[i]); - var subject = ""; if (msgHdr.flags & Ci.nsMsgMessageFlags.HasRe) { subject = "Re: "; } - if (msgHdr.mime2DecodedSubject) { - subject += msgHdr.mime2DecodedSubject; + if (msgSubject) { + subject += msgSubject; } if (subject) { menuText += subject + " - "; } - menuText += msgHdr.mime2DecodedAuthor; + menuText += msgAuthor; newMenuItem = document.createXULElement("menuitem"); newMenuItem.setAttribute("label", menuText); relPos += isBackMenu ? -1 : 1; diff -Nru thunderbird-68.3.0/comm/mail/base/content/messenger.css thunderbird-68.4.1/comm/mail/base/content/messenger.css --- thunderbird-68.3.0/comm/mail/base/content/messenger.css 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/base/content/messenger.css 2020-01-09 03:30:22.000000000 +0000 @@ -164,8 +164,8 @@ /* Rules to help integrate WebExtension buttons */ .webextension-action > .toolbarbutton-badge-stack > .toolbarbutton-icon { - height: 16px; - width: 16px; + height: 18px; + width: 18px; } @media not all and (min-resolution: 1.1dppx) { diff -Nru thunderbird-68.3.0/comm/mail/base/content/msgMail3PaneWindow.js thunderbird-68.4.1/comm/mail/base/content/msgMail3PaneWindow.js --- thunderbird-68.3.0/comm/mail/base/content/msgMail3PaneWindow.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/base/content/msgMail3PaneWindow.js 2020-01-09 03:30:22.000000000 +0000 @@ -375,7 +375,9 @@ if (aMsgWindowInitialized) { messenger.setWindow(null, null); messenger.setWindow(window, msgWindow); - ReloadMessage(); + // Hack to make sure that the message is re-displayed + // with the correct charset. + setTimeout(ReloadMessage); } // The quick filter bar gets badly lied to due to standard XUL/XBL problems, diff -Nru thunderbird-68.3.0/comm/mail/base/content/nsContextMenu.js thunderbird-68.4.1/comm/mail/base/content/nsContextMenu.js --- thunderbird-68.3.0/comm/mail/base/content/nsContextMenu.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/base/content/nsContextMenu.js 2020-01-09 03:30:22.000000000 +0000 @@ -37,7 +37,7 @@ this.target = null; this.menu = null; this.onTextInput = false; - this.onEditableArea = false; + this.onEditable = false; this.onImage = false; this.onLoadedImage = false; this.onCanvas = false; @@ -87,7 +87,10 @@ return; } - this.isContentSelected = this.isContentSelection(); + this.selectionInfo = BrowserUtils.getSelectionDetails(window); + this.isContentSelected = !this.selectionInfo.docSelectionIsCollapsed; + this.textSelected = this.selectionInfo.text; + this.isTextSelected = !!this.textSelected.length; this.hasPageMenu = false; if (!aIsShift) { @@ -107,12 +110,13 @@ onVideo: this.onVideo, onAudio: this.onAudio, onCanvas: this.onCanvas, - onEditableArea: this.onEditableArea, + onEditable: this.onEditable, srcUrl: this.mediaURL, pageUrl: this.browser ? this.browser.currentURI.spec : undefined, + linkText: this.onLink ? this.linkText() : undefined, linkUrl: this.linkURL, selectionText: this.isTextSelected - ? this.selectionInfo.text + ? this.selectionInfo.fullText : undefined, }; if (document.popupNode.closest("tree") == gFolderDisplay.tree) { @@ -157,10 +161,7 @@ let canSpell = gSpellChecker.canSpellCheck; let onMisspelling = gSpellChecker.overMisspelling; this.showItem("mailContext-spell-check-enabled", canSpell); - this.showItem( - "mailContext-spell-separator", - canSpell || this.onEditableArea - ); + this.showItem("mailContext-spell-separator", canSpell || this.onEditable); if (canSpell) { document .getElementById("mailContext-spell-check-enabled") @@ -196,7 +197,7 @@ ); gSpellChecker.addDictionaryListToMenu(dictMenu, dictSep); this.showItem("mailContext-spell-add-dictionaries-main", false); - } else if (this.onEditableArea) { + } else if (this.onEditable) { // when there is no spellchecker but we might be able to spellcheck // add the add to dictionaries item. This will ensure that people // with no dictionaries will be able to download them @@ -607,7 +608,7 @@ this.onLoadedImage = false; this.onMetaDataItem = false; this.onTextInput = false; - this.onEditableArea = false; + this.onEditable = false; this.imageURL = ""; this.onLink = false; this.onVideo = false; @@ -623,7 +624,7 @@ // Set up early the right flags for editable / not editable. let editFlags = SpellCheckHelper.isEditable(this.target, window); this.onTextInput = (editFlags & SpellCheckHelper.TEXTINPUT) !== 0; - this.onEditableArea = (editFlags & SpellCheckHelper.EDITABLE) !== 0; + this.onEditable = (editFlags & SpellCheckHelper.EDITABLE) !== 0; // First, do checks for nodes that never have children. if (this.target.nodeType == Node.ELEMENT_NODE) { @@ -649,7 +650,7 @@ (SpellCheckHelper.INPUT | SpellCheckHelper.TEXTAREA) ) { if (!this.target.readOnly) { - this.onEditableArea = true; + this.onEditable = true; gSpellChecker.init(this.target.editor); gSpellChecker.initFromEvent( document.popupRangeParent, diff -Nru thunderbird-68.3.0/comm/mail/base/modules/DNS.jsm thunderbird-68.4.1/comm/mail/base/modules/DNS.jsm --- thunderbird-68.3.0/comm/mail/base/modules/DNS.jsm 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/base/modules/DNS.jsm 2020-01-09 03:30:22.000000000 +0000 @@ -0,0 +1,473 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This module is responsible for performing DNS queries using ctypes for +// loading system DNS libraries on Linux, Mac and Windows. + +if (typeof Components !== "undefined") { + var { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm"); + var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + var { BasePromiseWorker } = ChromeUtils.import( + "resource://gre/modules/PromiseWorker.jsm" + ); +} + +var LOCATION = "resource:///modules/DNS.jsm"; + +// These constants are luckily shared, but with different names +var NS_T_TXT = 16; // DNS_TYPE_TXT +var NS_T_SRV = 33; // DNS_TYPE_SRV +var NS_T_MX = 15; // DNS_TYPE_MX + +// For Linux and Mac. +function load_libresolv() { + this._open(); +} + +load_libresolv.prototype = { + library: null, + + // Tries to find and load library. + _open() { + function findLibrary() { + let lastException = null; + let libnames = [ + ctypes.libraryName("resolv.9"), + ctypes.libraryName("resolv"), + ]; + for (let libname of libnames) { + try { + return ctypes.open(libname); + } catch (ex) { + lastException = ex; + } + } + throw new Error( + "Could not find libresolv in any of " + + libnames + + " Exception: " + + lastException + + "\n" + ); + } + + // Declaring functions to be able to call them. + function declare(aSymbolNames, ...aArgs) { + let lastException = null; + if (!Array.isArray(aSymbolNames)) { + aSymbolNames = [aSymbolNames]; + } + + for (let name of aSymbolNames) { + try { + return library.declare(name, ...aArgs); + } catch (ex) { + lastException = ex; + } + } + library.close(); + throw new Error( + "Failed to declare " + + aSymbolNames + + " Exception: " + + lastException + + "\n" + ); + } + + let library = (this.library = findLibrary()); + this.res_search = declare( + ["res_9_search", "res_search", "__res_search"], + ctypes.default_abi, + ctypes.int, + ctypes.char.ptr, + ctypes.int, + ctypes.int, + ctypes.unsigned_char.ptr, + ctypes.int + ); + this.res_query = declare( + ["res_9_query", "res_query", "__res_query"], + ctypes.default_abi, + ctypes.int, + ctypes.char.ptr, + ctypes.int, + ctypes.int, + ctypes.unsigned_char.ptr, + ctypes.int + ); + this.dn_expand = declare( + ["res_9_dn_expand", "dn_expand", "__dn_expand"], + ctypes.default_abi, + ctypes.int, + ctypes.unsigned_char.ptr, + ctypes.unsigned_char.ptr, + ctypes.unsigned_char.ptr, + ctypes.char.ptr, + ctypes.int + ); + this.dn_skipname = declare( + ["res_9_dn_skipname", "dn_skipname", "__dn_skipname"], + ctypes.default_abi, + ctypes.int, + ctypes.unsigned_char.ptr, + ctypes.unsigned_char.ptr + ); + this.ns_get16 = declare( + ["res_9_ns_get16", "ns_get16"], + ctypes.default_abi, + ctypes.unsigned_int, + ctypes.unsigned_char.ptr + ); + this.ns_get32 = declare( + ["res_9_ns_get32", "ns_get32"], + ctypes.default_abi, + ctypes.unsigned_long, + ctypes.unsigned_char.ptr + ); + + this.QUERYBUF_SIZE = 1024; + this.NS_MAXCDNAME = 255; + this.NS_HFIXEDSZ = 12; + this.NS_QFIXEDSZ = 4; + this.NS_RRFIXEDSZ = 10; + this.NS_C_IN = 1; + }, + + close() { + this.library.close(); + this.library = null; + }, + + // Maps record to SRVRecord, TXTRecord, or MXRecord according to aTypeID and + // returns it. + _mapAnswer(aTypeID, aAnswer, aIdx, aLength) { + if (aTypeID == NS_T_SRV) { + let prio = this.ns_get16(aAnswer.addressOfElement(aIdx)); + let weight = this.ns_get16(aAnswer.addressOfElement(aIdx + 2)); + let port = this.ns_get16(aAnswer.addressOfElement(aIdx + 4)); + + let hostbuf = ctypes.char.array(this.NS_MAXCDNAME)(); + let hostlen = this.dn_expand( + aAnswer.addressOfElement(0), + aAnswer.addressOfElement(aLength), + aAnswer.addressOfElement(aIdx + 6), + hostbuf, + this.NS_MAXCDNAME + ); + let host = hostlen > -1 ? hostbuf.readString() : null; + return new SRVRecord(prio, weight, host, port); + } else if (aTypeID == NS_T_TXT) { + // TODO should only read dataLength characters. + let data = ctypes.unsigned_char.ptr(aAnswer.addressOfElement(aIdx + 1)); + return new TXTRecord(data.readString()); + } else if (aTypeID == NS_T_MX) { + let prio = this.ns_get16(aAnswer.addressOfElement(aIdx)); + + let hostbuf = ctypes.char.array(this.NS_MAXCDNAME)(); + let hostlen = this.dn_expand( + aAnswer.addressOfElement(0), + aAnswer.addressOfElement(aLength), + aAnswer.addressOfElement(aIdx + 2), + hostbuf, + this.NS_MAXCDNAME + ); + let host = hostlen > -1 ? hostbuf.readString() : null; + return new MXRecord(prio, host); + } + return {}; + }, + + // Performs a DNS query for aTypeID on a certain address (aName) and returns + // array of records of aTypeID. + lookup(aName, aTypeID) { + let qname = ctypes.char.array()(aName); + let answer = ctypes.unsigned_char.array(this.QUERYBUF_SIZE)(); + let length = this.res_search( + qname, + this.NS_C_IN, + aTypeID, + answer, + this.QUERYBUF_SIZE + ); + + // There is an error. + if (length < 0) { + return -1; + } + + let results = []; + let idx = this.NS_HFIXEDSZ; + + let qdcount = this.ns_get16(answer.addressOfElement(4)); + let ancount = this.ns_get16(answer.addressOfElement(6)); + + for (let qdidx = 0; qdidx < qdcount && idx < length; qdidx++) { + idx += + this.NS_QFIXEDSZ + + this.dn_skipname( + answer.addressOfElement(idx), + answer.addressOfElement(length) + ); + } + + for (let anidx = 0; anidx < ancount && idx < length; anidx++) { + idx += this.dn_skipname( + answer.addressOfElement(idx), + answer.addressOfElement(length) + ); + let rridx = idx; + let type = this.ns_get16(answer.addressOfElement(rridx)); + let dataLength = this.ns_get16(answer.addressOfElement(rridx + 8)); + + idx += this.NS_RRFIXEDSZ; + + if (type === aTypeID) { + let resource = this._mapAnswer(aTypeID, answer, idx, length); + resource.type = type; + resource.nsclass = this.ns_get16(answer.addressOfElement(rridx + 2)); + resource.ttl = this.ns_get32(answer.addressOfElement(rridx + 4)) | 0; + results.push(resource); + } + idx += dataLength; + } + return results; + }, +}; + +// For Windows. +function load_dnsapi() { + this._open(); +} + +load_dnsapi.prototype = { + library: null, + + // Tries to find and load library. + _open() { + function declare(aSymbolName, ...aArgs) { + try { + return library.declare(aSymbolName, ...aArgs); + } catch (ex) { + throw new Error( + "Failed to declare " + aSymbolName + " Exception: " + ex + "\n" + ); + } + } + + let library = (this.library = ctypes.open(ctypes.libraryName("DnsAPI"))); + + this.DNS_SRV_DATA = ctypes.StructType("DNS_SRV_DATA", [ + { pNameTarget: ctypes.jschar.ptr }, + { wPriority: ctypes.unsigned_short }, + { wWeight: ctypes.unsigned_short }, + { wPort: ctypes.unsigned_short }, + { Pad: ctypes.unsigned_short }, + ]); + + this.DNS_TXT_DATA = ctypes.StructType("DNS_TXT_DATA", [ + { dwStringCount: ctypes.unsigned_long }, + { pStringArray: ctypes.jschar.ptr.array(1) }, + ]); + + this.DNS_MX_DATA = ctypes.StructType("DNS_MX_DATA", [ + { pNameTarget: ctypes.jschar.ptr }, + { wPriority: ctypes.unsigned_short }, + { Pad: ctypes.unsigned_short }, + ]); + + this.DNS_RECORD = ctypes.StructType("_DnsRecord"); + this.DNS_RECORD.define([ + { pNext: this.DNS_RECORD.ptr }, + { pName: ctypes.jschar.ptr }, + { wType: ctypes.unsigned_short }, + { wDataLength: ctypes.unsigned_short }, + { Flags: ctypes.unsigned_long }, + { dwTtl: ctypes.unsigned_long }, + { dwReserved: ctypes.unsigned_long }, + { Data: this.DNS_SRV_DATA }, // it's a union, can be cast to many things + ]); + + this.PDNS_RECORD = ctypes.PointerType(this.DNS_RECORD); + this.DnsQuery_W = declare( + "DnsQuery_W", + ctypes.winapi_abi, + ctypes.long, + ctypes.jschar.ptr, + ctypes.unsigned_short, + ctypes.unsigned_long, + ctypes.voidptr_t, + this.PDNS_RECORD.ptr, + ctypes.voidptr_t.ptr + ); + this.DnsRecordListFree = declare( + "DnsRecordListFree", + ctypes.winapi_abi, + ctypes.void_t, + this.PDNS_RECORD, + ctypes.int + ); + + this.ERROR_SUCCESS = ctypes.Int64(0); + this.DNS_QUERY_STANDARD = 0; + this.DnsFreeRecordList = 1; + }, + + close() { + this.library.close(); + this.library = null; + }, + + // Maps record to SRVRecord, TXTRecord, or MXRecord according to aTypeID and + // returns it. + _mapAnswer(aTypeID, aData) { + if (aTypeID == NS_T_SRV) { + let srvdata = ctypes.cast(aData, this.DNS_SRV_DATA); + + return new SRVRecord( + srvdata.wPriority, + srvdata.wWeight, + srvdata.pNameTarget.readString(), + srvdata.wPort + ); + } else if (aTypeID == NS_T_TXT) { + let txtdata = ctypes.cast(aData, this.DNS_TXT_DATA); + if (txtdata.dwStringCount > 0) { + return new TXTRecord(txtdata.pStringArray[0].readString()); + } + } else if (aTypeID == NS_T_MX) { + let mxdata = ctypes.cast(aData, this.DNS_MX_DATA); + return new MXRecord(mxdata.wPriority, mxdata.pNameTarget.readString()); + } + return {}; + }, + + // Performs a DNS query for aTypeID on a certain address (aName) and returns + // array of records of aTypeID (e.g. SRVRecord, TXTRecord, or MXRecord). + lookup(aName, aTypeID) { + let queryResultsSet = this.PDNS_RECORD(); + let qname = ctypes.jschar.array()(aName); + let dnsStatus = this.DnsQuery_W( + qname, + aTypeID, + this.DNS_QUERY_STANDARD, + null, + queryResultsSet.address(), + null + ); + + // There is an error. + if (ctypes.Int64.compare(dnsStatus, this.ERROR_SUCCESS) != 0) { + return -1; + } + + let results = []; + for ( + let presult = queryResultsSet; + presult && !presult.isNull(); + presult = presult.contents.pNext + ) { + let result = presult.contents; + if (result.wType == aTypeID) { + let resource = this._mapAnswer(aTypeID, result.Data); + resource.type = result.wType; + resource.nsclass = 0; + resource.ttl = result.dwTtl | 0; + results.push(resource); + } + } + + this.DnsRecordListFree(queryResultsSet, this.DnsFreeRecordList); + return results; + }, +}; + +// Used to make results of different libraries consistent for SRV queries. +function SRVRecord(aPrio, aWeight, aHost, aPort) { + this.prio = aPrio; + this.weight = aWeight; + this.host = aHost; + this.port = aPort; +} + +// Used to make results of different libraries consistent for TXT queries. +function TXTRecord(aData) { + this.data = aData; +} + +// Used to make results of different libraries consistent for MX queries. +function MXRecord(aPrio, aHost) { + this.prio = aPrio; + this.host = aHost; +} + +if (typeof Components === "undefined") { + /* eslint-env worker */ + + // We are in a worker, wait for our message then execute the wanted method. + importScripts("resource://gre/modules/workers/require.js"); + let PromiseWorker = require("resource://gre/modules/workers/PromiseWorker.js"); + + let worker = new PromiseWorker.AbstractWorker(); + worker.dispatch = function(aMethod, aArgs = []) { + return self[aMethod](...aArgs); + }; + worker.postMessage = function(...aArgs) { + self.postMessage(...aArgs); + }; + worker.close = function() { + self.close(); + }; + self.addEventListener("message", msg => worker.handleMessage(msg)); + + // eslint-disable-next-line no-unused-vars + function execute(aOS, aMethod, aArgs) { + let DNS = aOS == "WINNT" ? new load_dnsapi() : new load_libresolv(); + return DNS[aMethod].apply(DNS, aArgs); + } +} else { + // We are loaded as a JSM, provide the async front that will start the + // worker. + var dns_async_front = { + /** + * Constants for use with the lookup function. + */ + TXT: NS_T_TXT, + SRV: NS_T_SRV, + MX: NS_T_MX, + + /** + * Do an asynchronous DNS lookup. The returned promise resolves with + * one of the Answer objects as defined above, or rejects with the + * error from the worker. + * + * Example: DNS.lookup("_caldavs._tcp.example.com", DNS.SRV) + * + * @param aName The aName to look up. + * @param aTypeID The RR type to look up as a constant. + * @return A promise resolved when completed. + */ + lookup(aName, aTypeID) { + let worker = new BasePromiseWorker(LOCATION); + return worker.post("execute", [ + Services.appinfo.OS, + "lookup", + [...arguments], + ]); + }, + + /** Convenience functions */ + srv(aName) { + return this.lookup(aName, NS_T_SRV); + }, + txt(aName) { + return this.lookup(aName, NS_T_TXT); + }, + mx(aName) { + return this.lookup(aName, NS_T_MX); + }, + }; + this.DNS = dns_async_front; + this.EXPORTED_SYMBOLS = ["DNS"]; +} diff -Nru thunderbird-68.3.0/comm/mail/base/modules/moz.build thunderbird-68.4.1/comm/mail/base/modules/moz.build --- thunderbird-68.3.0/comm/mail/base/modules/moz.build 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/base/modules/moz.build 2020-01-09 03:30:22.000000000 +0000 @@ -7,6 +7,7 @@ 'AttachmentChecker.jsm', 'DBViewWrapper.jsm', 'DisplayNameUtils.jsm', + 'DNS.jsm', 'ExtensionsUI.jsm', 'GlobalPopupNotifications.jsm', 'MailConsts.jsm', diff -Nru thunderbird-68.3.0/comm/mail/components/accountcreation/content/emailWizard.js thunderbird-68.4.1/comm/mail/components/accountcreation/content/emailWizard.js --- thunderbird-68.3.0/comm/mail/components/accountcreation/content/emailWizard.js 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/components/accountcreation/content/emailWizard.js 2020-01-09 03:30:22.000000000 +0000 @@ -334,10 +334,11 @@ _show("next_button"); _disable("next_button"); // will be enabled by code + _show("manual-edit_button"); + _disable("manual-edit_button"); _hide("half-manual-test_button"); _hide("create_button"); _hide("stop_button"); - _hide("manual-edit_button"); _hide("advanced-setup_button"); } else if (modename == "find-config") { _show("status_area"); @@ -453,6 +454,7 @@ this.onStop(); } this.switchToMode("start"); + this.checkStartDone(); }, getConcreteConfig() { @@ -500,7 +502,6 @@ onInputEmail() { this._email = e("email").value; this.onStartOver(); - this.checkStartDone(); }, onInputRealname() { @@ -510,12 +511,12 @@ onInputUsername() { this._exchangeUsername = e("usernameEx").value; - this.checkStartDone(); + this.onStartOver(); }, onInputPassword() { this._password = e("password").value; - this.checkStartDone(); + this.onStartOver(); }, /** @@ -584,8 +585,12 @@ if (this.validateEmailMinimally(this._email) && this._realname) { this._domain = this._email.split("@")[1].toLowerCase(); _enable("next_button"); + _enable("manual-edit_button"); + _hide("provisioner_button"); } else { _disable("next_button"); + _disable("manual-edit_button"); + _show("provisioner_button"); } }, @@ -624,11 +629,11 @@ self.stopSpinner(call.foundMsg); self.foundConfig(config); }, - function(e) { + function(e, allErrors) { // all failed self._abortable = null; self.removeStatusLines(); - if (e instanceof CancelledException) { + if (allErrors.some(e => e instanceof CancelledException)) { return; } @@ -674,6 +679,7 @@ call = priority.addCall(); this.addStatusLine("looking_up_settings_mx", call); + // "found_settings_db" is correct. We display the same message for both db and mx cases. call.foundMsg = "found_settings_db"; fetch = fetchConfigForMX( domain, @@ -693,15 +699,18 @@ call.successCallback(), (e, allErrors) => { // Must call error callback in any case to stop the discover mode. - call.errorCallback()(e); // ()(e) is correct - if ( - e.code == 401 || - (allErrors && allErrors.find(e => e.code == 401)) - ) { - // Auth failed + let errorCallback = call.errorCallback(); + if (allErrors.some(e => e.code == 401)) { + // Auth failed. // Ask user for username. + this.onStartOver(); + this.stopSpinner(); // clears status message _show("usernameRow"); - this.switchToMode("start"); + _show("status-area"); + _enable("manual-edit_button"); + errorCallback(new CancelledException()); + } else { + errorCallback(e); } } ); @@ -783,7 +792,56 @@ let successCallback = () => { this._abortable = null; e("status_area").setAttribute("status", "result"); - this.displayConfigResult(config); + // For Office365, do a pre-verification of whether IMAP works. If it fails + // due to wrong password, make the user aware. If it fails due to other + // reasons (mainly MFA enforced), make Exchange the default. + // We do this since the account may have MFA enabled and that can't yet be + // used with IMAP/POP. + if ( + config.incoming.hostname == "outlook.office365.com" && + (config.incoming.type == "imap" || config.incoming.type == "pop3") && + config.incomingAlternatives.some(i => i.type == "exchange") + ) { + this.startSpinner("looking_up_settings_exchange"); + this._currentConfig = config; + let configFilledIn = this.getConcreteConfig(); + this.checkOffice365Creds( + configFilledIn, + () => { + // Password valid: check whether IMAP works. + verifyConfig( + configFilledIn, + false, + this._parentMsgWindow, + testedConfig => { + // IMAP worked + this.stopSpinner("found_settings_exchange"); + this.displayConfigResult(testedConfig); + }, + ex => { + // IMAP failed: make Exchange the default. + config.incomingAlternatives.unshift(config.incoming); + config.incoming = config.incomingAlternatives.find( + alt => alt.type == "exchange" + ); + config.incomingAlternatives = config.incomingAlternatives.filter( + alt => alt != config.incoming + ); + this.stopSpinner("found_settings_exchange"); + this.displayConfigResult(config); + } + ); + }, + () => { + // Invalid password: show the error and let user correct it. + this.onStartOver(); + _show("status-area"); + this.showErrorStatus("user_pass_invalid"); + } + ); + } else { + this.displayConfigResult(config); + } }; this._abortable = getAddonsList(config, successCallback, e => { successCallback(); @@ -792,6 +850,41 @@ }, /** + * Office365 AutoDiscover gives us specific error codes for + * invalid password and MFA enforced, so we can differentiate that. + * @param {Function} successCallback - function to be called in case the + * credentials were not explicitedly invalid. + * @param {Function} invalidPassword - function to be called in case the + * credentials were explicitely invalid. + */ + checkOffice365Creds(configFilledIn, successCallback, invalidPassword) { + let fetch = new FetchHTTP( + "https://autodiscover-s.outlook.com/Autodiscover/Autodiscover.xml", + { + username: configFilledIn.incoming.username, + password: configFilledIn.incoming.password, + allowAuthPrompt: false, + allowCache: false, + headers: { + Cookie: "", + }, + timeout: 10000, + }, + successCallback, + ex => { + let err = fetch._request.getResponseHeader("X-AutoDiscovery-Error"); + gEmailWizardLogger.info("O365 X-AutoDiscovery-Error: " + err); + if (err && err.includes(":InvalidCreds:")) { + invalidPassword(); + } else { + successCallback(); + } + } + ); + fetch.start(); + }, + + /** * [Stop] button click handler. * This allows the user to abort any longer operation, esp. network activity. * We currently have 3 such cases here: @@ -974,7 +1067,6 @@ _hide("result_addon_install"); _enable("create_button"); } else { - _hide("status_area"); _show("result_addon_intro"); var msg = gStringsBundle.getString("addon-intro"); if ( diff -Nru thunderbird-68.3.0/comm/mail/components/accountcreation/content/emailWizard.xul thunderbird-68.4.1/comm/mail/components/accountcreation/content/emailWizard.xul --- thunderbird-68.3.0/comm/mail/components/accountcreation/content/emailWizard.xul 2019-12-01 14:29:43.000000000 +0000 +++ thunderbird-68.4.1/comm/mail/components/accountcreation/content/emailWizard.xul 2020-01-09 03:30:22.000000000 +0000 @@ -158,6 +158,16 @@