diff -Nru thunderbird-31.3.0+build1/configure.in thunderbird-31.4.0+build1/configure.in --- thunderbird-31.3.0+build1/configure.in 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/configure.in 2015-01-12 17:29:34.000000000 +0000 @@ -234,7 +234,7 @@ # Make the config.status file executable chmod +x $CONFIG_STATUS -_SUBDIR_CONFIG_ARGS="$ac_configure_args" +_SUBDIR_CONFIG_ARGS="$ac_configure_args --with-intl-api" if test -n "$UNIFY_DIST"; then # Make --with-unify-dist point to the right path _SUBDIR_CONFIG_ARGS="$_SUBDIR_CONFIG_ARGS --with-unify-dist=$UNIFY_DIST" diff -Nru thunderbird-31.3.0+build1/debian/changelog thunderbird-31.4.0+build1/debian/changelog --- thunderbird-31.3.0+build1/debian/changelog 2014-11-28 19:41:25.000000000 +0000 +++ thunderbird-31.4.0+build1/debian/changelog 2015-01-12 18:31:12.000000000 +0000 @@ -1,3 +1,10 @@ +thunderbird (1:31.4.0+build1-0ubuntu0.14.10.1) utopic-security; urgency=medium + + * New upstream stable release (THUNDERBIRD_31_4_0_BUILD1) + - see USN-2460-1 + + -- Chris Coulson Mon, 12 Jan 2015 18:30:02 +0000 + thunderbird (1:31.3.0+build1-0ubuntu0.14.10.1) utopic-security; urgency=medium * New upstream stable release (THUNDERBIRD_31_3_0_BUILD1) diff -Nru thunderbird-31.3.0+build1/im/installer/package-manifest.in thunderbird-31.4.0+build1/im/installer/package-manifest.in --- thunderbird-31.3.0+build1/im/installer/package-manifest.in 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/im/installer/package-manifest.in 2015-01-12 17:29:34.000000000 +0000 @@ -484,6 +484,7 @@ ; extensions @BINPATH@/components/addonManager.js @BINPATH@/components/amContentHandler.js +@BINPATH@/components/amInstallTrigger.js @BINPATH@/components/amWebInstallListener.js @BINPATH@/components/nsBlocklistService.js #ifdef MOZ_UPDATER diff -Nru thunderbird-31.3.0+build1/l10n/changesets thunderbird-31.4.0+build1/l10n/changesets --- thunderbird-31.3.0+build1/l10n/changesets 2014-11-28 19:28:57.000000000 +0000 +++ thunderbird-31.4.0+build1/l10n/changesets 2015-01-12 17:59:58.000000000 +0000 @@ -1,55 +1,55 @@ -ar 1374:257b4ef0c749 -ast 1255:50f8b9502911 -be 1585:0e54c06ab785 -bg 843:435f02923047 -bn-BD 811:25ecfbe25e7f -br 966:7cc0d3765cb0 -ca 2171:b319d431fead -cs 3453:c3a2fe31f26e -da 1831:ad1927a730c8 -de 4435:e81eb42de569 -el 1135:63b348f78be6 -en-GB 1680:d5caeec39809 -es-AR 2350:112c98841eb5 -es-ES 3700:9376461e7152 -et 1571:1c9868059b1e -eu 1310:cfa4f7968db3 -fi 2000:8d859df64187 -fr 6528:1fca5bb64c56 -fy-NL 2258:d9a319284c58 -ga-IE 1522:c1b9aea75032 -gd 1406:a7d17a62d242 -gl 2796:45b10bd20242 -he 1288:590fca1637db -hr 1583:cc5756d0c5c1 -hu 1922:d38467e7d7cb -hy-AM 922:97d59af27536 -id 1409:78e3d2a9945d -is 1109:f12b2544af17 -it 4787:0b8495e9d02f -ja 2078:7ffa384afefa -ja-JP-mac 1744:a7dedd8e9cef -ko 1738:e77fb5b6cca3 -lt 2639:eaaf8dd752cc -nb-NO 2432:7e86faa5321a -nl 5043:f8d69dfe870f -nn-NO 1365:4dfed56d1a93 -pa-IN 1651:edebd071d977 -pl 6314:51d7da384aac -pt-BR 1685:b4ce22dc94ef -pt-PT 2969:e7ab8e26f6ca -rm 1100:be613b7a039e -ro 1217:aa9daebccf07 -ru 3721:cb0722f1076e -si 1123:c2058f28629f -sk 1846:f4aa6ccf275e -sl 1797:1ce84cfb84d4 -sq 1600:3710a5a924fc -sr 888:28d0c45a0523 -sv-SE 4340:5443bb7c27e0 -ta-LK 671:fc74a2dd50f7 -tr 1752:2283c489c2fb -uk 2534:04d4441d4e34 -vi 845:e4df9bc7f832 -zh-CN 2111:58a947cf6ae8 -zh-TW 2417:a9238c6ca79e +ar 1404:aa0844f79c69 +ast 1286:0ed3254065e7 +be 1622:2f450428f4c2 +bg 884:4d53807a9f49 +bn-BD 842:e7af3bebad8c +br 1007:2fb01f150b9d +ca 2230:cdd430582148 +cs 3503:1cfd0a866eb7 +da 1877:50135f40f1c1 +de 4499:233414b839af +el 1167:09fc5c4d8731 +en-GB 1718:5db156818222 +es-AR 2398:92e68e5ca0f6 +es-ES 3763:13f3584ce58f +et 1603:8d95a016e094 +eu 1349:bc2e1bc4f572 +fi 2043:8bb3b446d2e2 +fr 6658:73cd1ecb4a88 +fy-NL 2301:91ca6f20a00c +ga-IE 1554:839671b36181 +gd 1437:65de568b3366 +gl 2874:8e6aaf3db78e +he 1302:0be21ed39543 +hr 1600:7937e6daa524 +hu 1966:f3bfc9a66ec3 +hy-AM 955:c49cf80ae6b7 +id 1435:e88f032284b3 +is 1139:d00353faa278 +it 4913:bc9b9faae0d8 +ja 2130:5130ead14cb1 +ja-JP-mac 1786:91bfe433fc3c +ko 1767:35601c093bf5 +lt 2691:d53274d9fe6c +nb-NO 2478:af6e40209a66 +nl 5146:efee29bbb3a5 +nn-NO 1381:6c224f451666 +pa-IN 1686:74ebf51fccfa +pl 6446:ed970635fdcf +pt-BR 1750:ab156e7eb2a3 +pt-PT 3007:d8bb78b7903e +rm 1115:67e82d112ca1 +ro 1250:9b0adbff1ce4 +ru 3785:5f329b7ae6e4 +si 1137:900dbb5b8476 +sk 1889:3d5dfea53790 +sl 1919:5ef84a9c032c +sq 1666:6bd7513468b7 +sr 916:8d1f1c75d09a +sv-SE 4387:5115715fd3fd +ta-LK 672:f6c2da5f4d96 +tr 1807:10d4aa9e537b +uk 2576:218e8200cc76 +vi 861:188b1485591a +zh-CN 2164:daaa3b7ff200 +zh-TW 2460:bf50d4cde638 diff -Nru thunderbird-31.3.0+build1/l10n/ro/mail/chrome/messenger/viewZoomOverlay.dtd thunderbird-31.4.0+build1/l10n/ro/mail/chrome/messenger/viewZoomOverlay.dtd --- thunderbird-31.3.0+build1/l10n/ro/mail/chrome/messenger/viewZoomOverlay.dtd 2014-11-28 19:25:20.000000000 +0000 +++ thunderbird-31.4.0+build1/l10n/ro/mail/chrome/messenger/viewZoomOverlay.dtd 2015-01-12 17:58:01.000000000 +0000 @@ -22,14 +22,15 @@ you can use these alternative items. Otherwise, their values should be empty. --> - - - + + + + - - + + diff -Nru thunderbird-31.3.0+build1/mail/base/modules/Windows8WindowFrameColor.jsm thunderbird-31.4.0+build1/mail/base/modules/Windows8WindowFrameColor.jsm --- thunderbird-31.3.0+build1/mail/base/modules/Windows8WindowFrameColor.jsm 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mail/base/modules/Windows8WindowFrameColor.jsm 2015-01-12 17:29:34.000000000 +0000 @@ -21,6 +21,10 @@ let windowFrameColor = WindowsRegistry.readRegKey(Ci.nsIWindowsRegKey.ROOT_KEY_CURRENT_USER, "Software\\Microsoft\\Windows\\DWM", "ColorizationColor"); + if (!windowFrameColor) { + // Seems to be the default color (hardcoded because of bug 1065998/1107902) + return [158, 158, 158]; + } // The color returned from the Registry is in decimal form. let windowFrameColorHex = windowFrameColor.toString(16); // Zero-pad the number just to make sure that it is 8 digits. diff -Nru thunderbird-31.3.0+build1/mail/components/compose/content/addressingWidgetOverlay.js thunderbird-31.4.0+build1/mail/components/compose/content/addressingWidgetOverlay.js --- thunderbird-31.3.0+build1/mail/components/compose/content/addressingWidgetOverlay.js 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mail/components/compose/content/addressingWidgetOverlay.js 2015-01-12 17:29:34.000000000 +0000 @@ -785,9 +785,7 @@ function awRecipientTextCommand(enterEvent, element) { - // Only add new row when enter was hit (not for tab/autocomplete select). - if (enterEvent) - awReturnHit(element); + awReturnHit(element); } function awRecipientKeyPress(event, element) diff -Nru thunderbird-31.3.0+build1/mail/config/version.txt thunderbird-31.4.0+build1/mail/config/version.txt --- thunderbird-31.3.0+build1/mail/config/version.txt 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mail/config/version.txt 2015-01-12 17:29:34.000000000 +0000 @@ -1 +1 @@ -31.3.0 +31.4.0 diff -Nru thunderbird-31.3.0+build1/mail/configure.in thunderbird-31.4.0+build1/mail/configure.in --- thunderbird-31.3.0+build1/mail/configure.in 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mail/configure.in 2015-01-12 17:29:34.000000000 +0000 @@ -95,7 +95,7 @@ fi if test -z "$MOZ_INCOMPLETE_EXTERNAL_LINKAGE"; then - MOZ_APP_COMPONENT_MODULES="MODULE(nsMailCompsModule) $MAIL_MODULE $LDAP_MODULE $MORK_MODULE" + MOZ_APP_COMPONENT_MODULES="MODULE(nsMailCompsModule) $MAIL_MODULE $LDAP_MODULE $MORK_MODULE $COLLATION_MODULE" MOZ_APP_EXTRA_LIBS="$LDAP_LIBS" fi diff -Nru thunderbird-31.3.0+build1/mail/confvars.sh thunderbird-31.4.0+build1/mail/confvars.sh --- thunderbird-31.3.0+build1/mail/confvars.sh 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mail/confvars.sh 2015-01-12 17:29:34.000000000 +0000 @@ -23,6 +23,11 @@ MOZ_MEDIA_NAVIGATOR=1 MOZ_MORK=1 MAIL_MODULE="MODULE(nsMailModule) MODULE(nsImportServiceModule)" +if test "$OS_ARCH" = "Darwin"; then + COLLATION_MODULE="MODULE(nsCollationRegistrar)" +else + COLLATION_MODULE= +fi MOZ_APP_VERSION_TXT=${_topsrcdir}/$MOZ_BUILD_APP/config/version.txt MOZ_APP_VERSION=`cat $MOZ_APP_VERSION_TXT` @@ -42,3 +47,4 @@ if test "$OS_TARGET" = "WINNT" -o "$OS_TARGET" = "Darwin"; then MOZ_FOLD_LIBS=1 fi +MOZ_PROFILE_MIGRATOR=1 diff -Nru thunderbird-31.3.0+build1/mail/installer/package-manifest.in thunderbird-31.4.0+build1/mail/installer/package-manifest.in --- thunderbird-31.3.0+build1/mail/installer/package-manifest.in 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mail/installer/package-manifest.in 2015-01-12 17:29:34.000000000 +0000 @@ -639,6 +639,7 @@ ; extensions @BINPATH@/components/addonManager.js @BINPATH@/components/amContentHandler.js +@BINPATH@/components/amInstallTrigger.js @BINPATH@/components/amWebInstallListener.js @BINPATH@/components/nsBlocklistService.js #ifdef MOZ_UPDATER diff -Nru thunderbird-31.3.0+build1/mailnews/addrbook/src/nsAbAutoCompleteSearch.js thunderbird-31.4.0+build1/mailnews/addrbook/src/nsAbAutoCompleteSearch.js --- thunderbird-31.3.0+build1/mailnews/addrbook/src/nsAbAutoCompleteSearch.js 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/addrbook/src/nsAbAutoCompleteSearch.js 2015-01-12 17:29:34.000000000 +0000 @@ -125,6 +125,42 @@ }, /** + * Gets the score of the (full) address, given the search input. We want + * results that match the beginning of a "word" in the result to score better + * than a result that matches only in the middle of the word. + * + * @param aAddress - full lower-cased address, including display name and address + * @param aSearchString - search string provided by user + * @return a score; a higher score is better than a lower one + */ + _getScore: function(aAddress, aSearchString) { + const BEST = 100; + // We'll do this case-insensitively and ignore the domain. + let atIdx = aAddress.lastIndexOf("@"); + if (atIdx != -1) // mail lists don't have an @ + aAddress = aAddress.substr(0, atIdx); + aSearchString = aSearchString.toLocaleLowerCase(); + let idx = aAddress.indexOf(aSearchString); + if (idx == 0) + return BEST; + if (idx == -1) + return 0; + + // We want to treat firstname, lastname and word boundary(ish) parts of + // the email address the same. E.g. for "John Doe (:xx) " + // all of these should score (almost) the same: "John", "Doe", "xx", + // ":xx:", "jd", "who". + let prevCh = aAddress.charAt(idx - 1); + if (/[ :."'(\-_<&]/.test(prevCh)) { + // -1, so exact begins-with match will still be the first hit. + return BEST - 1; + } + + // The match was inside a word -> we don't care about the position. + return 0; + }, + + /** * Searches cards in the given directory. If a card is matched (and isn't * a mailing list) then the function will add a result for each email address * that exists. @@ -201,30 +237,26 @@ * * @param directory The directory that the card is in. * @param card The card that could be a duplicate. - * @param emailAddress The emailAddress (name/address combination) to check - * for duplicates against. + * @param lcEmailAddress The emailAddress (name/address combination) to check + * for duplicates against. Lowercased. * @param currentResults The current results list. */ - _checkDuplicate: function _checkDuplicate(directory, card, emailAddress, - currentResults) { - let lcEmailAddress = emailAddress.toLocaleLowerCase(); + _checkDuplicate: function (directory, card, lcEmailAddress, currentResults) { let existingResult = currentResults._collectedValues.get(lcEmailAddress); - let popIndex = this._getPopularityIndex(directory, card); + if (!existingResult) + return false; - if (existingResult) { - // It's a duplicate, is the new one more popular? - if (popIndex > existingResult.popularity) { - // Yes it is, so delete this element, return false and allow - // _addToResult to sort the new element into the correct place. - currentResults._collectedValues.delete(lcEmailAddress); - return false; - } - // Not more popular, but still a duplicate. Return true and _addToResult - // will just forget about it. - return true; + let popIndex = this._getPopularityIndex(directory, card); + // It's a duplicate, is the new one more popular? + if (popIndex > existingResult.popularity) { + // Yes it is, so delete this element, return false and allow + // _addToResult to sort the new element into the correct place. + currentResults._collectedValues.delete(lcEmailAddress); + return false; } - - return false; + // Not more popular, but still a duplicate. Return true and _addToResult + // will just forget about it. + return true; }, /** @@ -250,19 +282,21 @@ return; let emailAddress = mbox.toString(); + let lcEmailAddress = emailAddress.toLocaleLowerCase(); // If it is a duplicate, then just return and don't add it. The // _checkDuplicate function deals with it all for us. - if (this._checkDuplicate(directory, card, emailAddress, result)) + if (this._checkDuplicate(directory, card, lcEmailAddress, result)) return; - result._collectedValues.set(emailAddress.toLocaleLowerCase(), { + result._collectedValues.set(lcEmailAddress, { value: emailAddress, comment: commentColumn, card: card, isPrimaryEmail: isPrimaryEmail, emailToUse: emailToUse, - popularity: this._getPopularityIndex(directory, card) + popularity: this._getPopularityIndex(directory, card), + score: this._getScore(lcEmailAddress, result.searchString) }); }, @@ -361,15 +395,16 @@ } result._searchResults = [...result._collectedValues.values()]; - // Order by descending popularity, then primary email before secondary - // for the same card, then for differing cards sort by email. - function order_by_popularity_and_email(a, b) { - return (b.popularity - a.popularity) || + result._searchResults.sort(function(a, b) { + // Order by 1) descending score, then 2) descending popularity, + // then 3) primary email before secondary for the same card, then + // 4) by differing cards sort by email. + return (b.score - a.score) || + (b.popularity - a.popularity) || ((a.card == b.card && a.isPrimaryEmail) ? -1 : 0) || ((a.value < b.value) ? -1 : (a.value == b.value) ? 0 : 1); // TODO: this should actually use a.value.localeCompare(b.value) . - } - result._searchResults.sort(order_by_popularity_and_email); + }); } if (result.matchCount) { diff -Nru thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch1.js thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch1.js --- thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch1.js 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch1.js 2015-01-12 17:29:34.000000000 +0000 @@ -12,19 +12,19 @@ // on a pattern rather just doing the odd spot check. // // Note the expected arrays are in expected sort order as well. -const results = [ { email: "d ", dirName: kPABData.dirName }, - { email: "di ", dirName: kPABData.dirName }, - { email: "dis ", dirName: kPABData.dirName }, - { email: "disp ", dirName: kPABData.dirName }, - { email: "displ ", dirName: kPABData.dirName }, - { email: "DisplayName1 ", +const results = [ { email: "d ", dirName: kPABData.dirName }, // 0 + { email: "di ", dirName: kPABData.dirName }, // 1 + { email: "dis ", dirName: kPABData.dirName }, // 2 + { email: "disp ", dirName: kPABData.dirName }, // 3 + { email: "displ ", dirName: kPABData.dirName }, // 4 + { email: "DisplayName1 ", // 5 dirName: kCABData.dirName }, - { email: "t ", dirName: kPABData.dirName }, - { email: "te ", dirName: kPABData.dirName }, - { email: "tes
  • ", dirName: kPABData.dirName }, + { email: "t ", dirName: kPABData.dirName }, // 6 + { email: "te ", dirName: kPABData.dirName }, // 7 + { email: "tes
  • ", dirName: kPABData.dirName }, // 8 // this contact has a nickname of "abcdef" - { email: "test ", dirName: kPABData.dirName } ]; - + { email: "test ", dirName: kPABData.dirName } // 9 + ]; const firstNames = [ { search: "f", expected: [5, 0, 1, 2, 3, 4, 9] }, { search: "fi", expected: [5, 0, 1, 3, 4] }, { search: "fir", expected: [5, 0, 1, 4] }, @@ -32,7 +32,7 @@ { search: "first", expected: [5, 1] }, { search: "firstn", expected: [5] } ]; -const lastNames = [ { search: "l", expected: [5, 0, 1, 2, 3, 4, 6, 7, 8, 9] }, +const lastNames = [ { search: "l", expected: [6, 7, 8, 9, 5, 0, 1, 2, 3, 4] }, { search: "la", expected: [5, 0, 2, 3, 4] }, { search: "las", expected: [5, 0, 3, 4] }, { search: "last", expected: [5, 0, 4] }, @@ -53,20 +53,20 @@ { search: "nickn", expected: [5, 3] }, { search: "nickna", expected: [5] } ]; -const emails = [ { search: "e", expected: [5, 0, 1, 2, 3, 4, 7, 8, 9] }, - { search: "em", expected: [5, 0, 1, 2, 4] }, - { search: "ema", expected: [5, 0, 1, 2] }, - { search: "emai", expected: [5, 1, 2] }, - { search: "email", expected: [5, 2] } ]; +const emails = [ { search: "e", expected: [0, 1, 2, 3, 4, 5, 7, 8, 9] }, + { search: "em", expected: [0, 1, 2, 4, 5] }, + { search: "ema", expected: [0, 1, 2, 5] }, + { search: "emai", expected: [1, 2, 5] }, + { search: "email", expected: [2, 5] } ]; // "l" case tested above -const lists = [ { search: "li", expected: [5, 0, 1, 2, 3, 4, 6, 7, 8] }, +const lists = [ { search: "li", expected: [6, 7, 8, 5, 0, 1, 2, 3, 4] }, { search: "lis", expected: [6, 7] }, { search: "list", expected: [6] }, - { search: "t", expected: [5, 0, 1, 4, 6, 7, 8, 9] }, - { search: "te", expected: [5, 7, 8, 9] }, - { search: "tes", expected: [5, 8, 9] }, - { search: "test", expected: [5, 9] }, + { search: "t", expected: [6, 7, 8, 9, 5, 0, 1, 4] }, + { search: "te", expected: [7, 8, 9, 5] }, + { search: "tes", expected: [8, 9, 5] }, + { search: "test", expected: [9, 5] }, { search: "abcdef", expected: [9] } // Bug 441586 ]; @@ -172,8 +172,8 @@ do_check_eq(obs._result.matchCount, 2); do_check_eq(obs._result.defaultIndex, 0); - do_check_eq(obs._result.getValueAt(0), "DisplayName1 "); - do_check_eq(obs._result.getLabelAt(0), "DisplayName1 "); + do_check_eq(obs._result.getValueAt(0), "dis "); + do_check_eq(obs._result.getLabelAt(0), "dis "); do_check_eq(obs._result.getCommentAt(0), ""); do_check_eq(obs._result.getStyleAt(0), "local-abook"); do_check_eq(obs._result.getImageAt(0), ""); @@ -198,9 +198,9 @@ do_check_eq(obs._result.matchCount, 2); do_check_eq(obs._result.defaultIndex, 0); - do_check_eq(obs._result.getValueAt(0), "DisplayName1 "); - do_check_eq(obs._result.getLabelAt(0), "DisplayName1 "); - do_check_eq(obs._result.getCommentAt(0), kCABData.dirName); + do_check_eq(obs._result.getValueAt(0), "dis "); + do_check_eq(obs._result.getLabelAt(0), "dis "); + do_check_eq(obs._result.getCommentAt(0), kPABData.dirName); do_check_eq(obs._result.getStyleAt(0), "local-abook"); do_check_eq(obs._result.getImageAt(0), ""); @@ -214,18 +214,27 @@ do_check_eq(obs._result.matchCount, 2); do_check_eq(obs._result.defaultIndex, 0); - do_check_eq(obs._result.getValueAt(0), "DisplayName1 "); - do_check_eq(obs._result.getLabelAt(0), "DisplayName1 "); - do_check_eq(obs._result.getCommentAt(0), kCABData.dirName); + do_check_eq(obs._result.getValueAt(0), "dis "); + do_check_eq(obs._result.getLabelAt(0), "dis "); + do_check_eq(obs._result.getCommentAt(0), kPABData.dirName); do_check_eq(obs._result.getStyleAt(0), "local-abook"); do_check_eq(obs._result.getImageAt(0), ""); // Now check multiple matches function checkInputItem(element, index, array) { - print("Checking " + element.search); + print("Search #" + index + ": search=" + element.search); acs.startSearch(element.search, param, null, obs); + for (var i = 0; i < obs._result.matchCount; i++) { + print("... got " + i + ": " + obs._result.getValueAt(i)); + } + + for (var i = 0; i < element.expected.length; i++) { + print("... expected " + i + " (result " + element.expected[i] + "): " + + results[element.expected[i]].email); + } + do_check_eq(obs._search, acs); do_check_eq(obs._result.searchString, element.search); do_check_eq(obs._result.searchResult, ACR.RESULT_SUCCESS); diff -Nru thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch3.js thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch3.js --- thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch3.js 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch3.js 2015-01-12 17:29:34.000000000 +0000 @@ -30,7 +30,7 @@ ]; const duplicates = [ - { search: "test", expected: [2, 1] }, + { search: "test", expected: [1, 2] }, { search: "first", expected: [6, 5, 3] }, { search: "(bracket)", expected: [7, 8] } ]; @@ -80,18 +80,24 @@ var obs = new acObserver(); function checkInputItem(element, index, array) { - print("Checking " + element.search); + print("Search #" + index + ": search=" + element.search); acs.startSearch(element.search, JSON.stringify({ type: "addr_to" }), null, obs); + for (var i = 0; i < obs._result.matchCount; i++) { + print("... got " + i + ": " + obs._result.getValueAt(i)); + } + + for (var i = 0; i < element.expected.length; i++) { + print("... expected " + i + " (card " + element.expected[i] + "): " + + cards[element.expected[i]].value); + } + do_check_eq(obs._search, acs); do_check_eq(obs._result.searchString, element.search); do_check_eq(obs._result.searchResult, ACR.RESULT_SUCCESS); do_check_eq(obs._result.errorDescription, null); do_check_eq(obs._result.matchCount, element.expected.length); - for (var i = 0; i < element.expected.length; ++i) - print(obs._result.getValueAt(i)); - for (var i = 0; i < element.expected.length; ++i) { do_check_eq(obs._result.getValueAt(i), cards[element.expected[i]].value); do_check_eq(obs._result.getLabelAt(i), cards[element.expected[i]].value); diff -Nru thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch4.js thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch4.js --- thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch4.js 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch4.js 2015-01-12 17:29:34.000000000 +0000 @@ -42,27 +42,27 @@ "testsort", "2testsort", "3testsort" ]; const expectedResults = [ [ "primary@test.invalid", - "second@test.invalid" ], // searching for primary/second returns - [ "primary@test.invalid", // both the emails as the new search query - "second@test.invalid" ], // looks in both the fields. + "second@test.invalid"], // searching for primary/second returns + [ "second@test.invalid", // both the emails as the new search query + "primary@test.invalid" ], // looks in both the fields. [ "test1@test.invalid", "test2@test.invalid" ], - [ "name@test.invalid", - "thename@test.invalid" ], + [ "thename@test.invalid", + "name@test.invalid"], [ "sortbasic ", "sortbasic " ], - [ "3testsort ", + [ "testsort ", + "testsort ", + "testsort ", + "testsort ", + "3testsort ", "3testsort ", "3testsort ", "3testsort ", "2testsort ", "2testsort ", "2testsort ", - "2testsort ", - "testsort ", - "testsort ", - "testsort ", - "testsort " ], + "2testsort "], [ "2testsort ", "2testsort ", "2testsort ", @@ -131,7 +131,7 @@ print("Checking Initial Searches"); function checkSearch(element, index, array) { - print("Checking " + element); + print("Search #" + index + ": search=" + element); acs.startSearch(element, JSON.stringify({ type: "addr_to" }), null, obs); do_check_eq(obs._search, acs); diff -Nru thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch5.js thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch5.js --- thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch5.js 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch5.js 2015-01-12 17:29:34.000000000 +0000 @@ -23,7 +23,7 @@ { search: "firs", expected: [0, 1] }, { search: "first", expected: [1] } ]; -const lastNames = [ { search: "l", expected: [4, 0, 1, 2, 3, 5, 6, 7, 8] }, +const lastNames = [ { search: "l", expected: [5, 6, 7, 8, 4, 0, 1, 2, 3] }, { search: "la", expected: [4, 0, 2, 3] }, { search: "las", expected: [4, 0, 3] }, { search: "last", expected: [4, 0] }, @@ -63,9 +63,18 @@ // Now check multiple matches function checkInputItem(element, index, array) { - print("Checking " + element.search); + print("Search #" + index + ": search=" + element.search); acs.startSearch(element.search, JSON.stringify({ type: "addr_to" }), null, obs); + for (var i = 0; i < obs._result.matchCount; i++) { + print("... got " + i + ": " + obs._result.getValueAt(i)); + } + + for (var i = 0; i < element.expected.length; i++) { + print("... expected " + i + " (card " + element.expected[i] + "): " + + results[element.expected[i]].email); + } + do_check_eq(obs._search, acs); do_check_eq(obs._result.searchString, element.search); do_check_eq(obs._result.searchResult, ACR.RESULT_SUCCESS); diff -Nru thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch6.js thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch6.js --- thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch6.js 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/test_nsAbAutoCompleteSearch6.js 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,145 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/** + * Tests for for nsAbAutoCompleteSearch scoring. + */ + +const ACR = Components.interfaces.nsIAutoCompleteResult; + +const cards = [ + { // 0 + email: "jd.who@example.com", displayName: "John Doe (:xx)", + popularityIndex: 0, firstName: "John", value: "John Doe (:xx) " + }, + + { // 1 + email: "janey_who@example.com", displayName: "Jane Doe", + popularityIndex: 0, value: "Jane Doe " + }, + + { // 2 + email: "pf@example.com", displayName: "Paul \"Shitbreak\" Finch", + popularityIndex: 0, value: "Paul \"Shitbreak\" Finch " + }, + + { // 3 + email: "js@example.com", displayName: "Janine (Stifflers Mom)", + popularityIndex: 0, value: "Janine (Stifflers Mom) " + }, + + { // 4 + email: "ex0@example.com", displayName: "Ajden", + popularityIndex: 0, value: "Ajden " + }, + + { // 5 + email: "5@example.com", displayName: "Foxx", + popularityIndex: 0, value: "Foxx <5@example.com>" + }, + + { // 6 + email: "6@example.com", displayName: "thewho", + popularityIndex: 0, value: "thewho <6@example.com>" + }, + + { // 7 + email: "7@example.com", displayName: "fakeshit", + popularityIndex: 0, value: "fakeshit <7@example.com>" + }, + + { // 8 + email: "8@example.com", displayName: "mastiff", + popularityIndex: 0, value: "mastiff <8@example.com>" + }, + + { // 9 + email: "9@example.com", displayName: "anyjohn", + popularityIndex: 0, value: "anyjohn <9@example.com>" + }, + + { // 10 + email: "10@example.com", displayName: "däsh l18n", + popularityIndex: 0, value: "däsh l18n <10@example.com>" + } +]; + +const inputs = [ + { search: "john", expected: [0, 9] }, + { search: "doe", expected: [1, 0] }, + { search: "jd", expected: [0, 4] }, + { search: "who", expected: [1, 0, 6] }, + { search: "xx", expected: [0, 5] }, + { search: "jan", expected: [1, 3] }, + { search: "sh", expected: [2, 10, 7] }, + { search: "st", expected: [3,8] } +]; + +function acObserver() {} + +acObserver.prototype = { + _search: null, + _result: null, + + onSearchResult: function (aSearch, aResult) { + this._search = aSearch; + this._result = aResult; + } +}; + +function run_test() +{ + // We set up the cards for this test manually as it is easier to set the + // popularity index and we don't need many. + + // Ensure all the directories are initialised. + MailServices.ab.directories; + + let ab = MailServices.ab.getDirectory(kPABData.URI); + + function createAndAddCard(element) { + var card = Cc["@mozilla.org/addressbook/cardproperty;1"] + .createInstance(Ci.nsIAbCard); + + card.primaryEmail = element.email; + card.displayName = element.displayName; + card.setProperty("PopularityIndex", element.popularityIndex); + card.firstName = element.firstName; + + ab.addCard(card); + } + + cards.forEach(createAndAddCard); + + // Test - duplicate elements + + var acs = Components.classes["@mozilla.org/autocomplete/search;1?name=addrbook"] + .getService(Components.interfaces.nsIAutoCompleteSearch); + + var obs = new acObserver(); + + function checkInputItem(element, index, array) { + print("Search #" + index + ": search=" + element.search); + acs.startSearch(element.search, JSON.stringify({ type: "addr_to" }), null, obs); + + for (var i = 0; i < obs._result.matchCount; i++) { + print("... got " + i + ": " + obs._result.getValueAt(i)); + } + + for (var i = 0; i < element.expected.length; i++) { + print("... expected " + i + " (card " + element.expected[i] + "): " + + cards[element.expected[i]].value); + } + + do_check_eq(obs._search, acs); + do_check_eq(obs._result.searchString, element.search); + do_check_eq(obs._result.searchResult, ACR.RESULT_SUCCESS); + do_check_eq(obs._result.errorDescription, null); + do_check_eq(obs._result.matchCount, element.expected.length); + + for (var i = 0; i < element.expected.length; ++i) { + do_check_eq(obs._result.getValueAt(i), cards[element.expected[i]].value); + do_check_eq(obs._result.getLabelAt(i), cards[element.expected[i]].value); + } + } + + inputs.forEach(checkInputItem); +} diff -Nru thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/xpcshell.ini thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/xpcshell.ini --- thunderbird-31.3.0+build1/mailnews/addrbook/test/unit/xpcshell.ini 2014-11-28 18:56:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/addrbook/test/unit/xpcshell.ini 2015-01-12 17:29:34.000000000 +0000 @@ -23,6 +23,7 @@ [test_nsAbAutoCompleteSearch3.js] [test_nsAbAutoCompleteSearch4.js] [test_nsAbAutoCompleteSearch5.js] +[test_nsAbAutoCompleteSearch6.js] [test_nsAbManager1.js] [test_nsAbManager2.js] [test_nsIAbCard.js] diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/moz.build thunderbird-31.4.0+build1/mailnews/intl/mac/moz.build --- thunderbird-31.3.0+build1/mailnews/intl/mac/moz.build 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/moz.build 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,19 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +UNIFIED_SOURCES += [ + 'nsCollationMacUC.cpp', + 'nsCollationRegistrar.cpp', + 'nsCollationRegistrarModule.cpp', + 'nsFixedCollationMacUCFactory.cpp', +] + +FINAL_LIBRARY = 'mail' +LOCAL_INCLUDES += [ + '/mozilla/intl/icu/source/common', + '/mozilla/intl/icu/source/i18n', + '/mozilla/intl/locale/src', +] diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationMacUC.cpp thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationMacUC.cpp --- thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationMacUC.cpp 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationMacUC.cpp 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,384 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsCollationMacUC.h" +#include "nsILocaleService.h" +#include "nsIPrefBranch.h" +#include "nsIPrefService.h" +#include "nsIServiceManager.h" +#include "prmem.h" +#include "nsString.h" + +namespace mailnews { + +NS_IMPL_ISUPPORTS(nsCollationMacUC, nsICollation) + +nsCollationMacUC::nsCollationMacUC() + : mInit(false) + , mHasCollator(false) + , mLocaleICU(nullptr) + , mLocale(nullptr) + , mLastStrength(-1) + , mCollatorICU(nullptr) + , mCollator(nullptr) + , mBuffer(nullptr) + , mBufferLen(1) + , mUseICU(true) +{ + nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); + if (prefs) { + prefs->GetBoolPref("intl.collation.mac.use_icu", &mUseICU); + } +} + +nsCollationMacUC::~nsCollationMacUC() +{ +#ifdef DEBUG + nsresult res = +#endif + CleanUpCollator(); + NS_ASSERTION(NS_SUCCEEDED(res), "CleanUpCollator failed"); + if (mUseICU) { + if (mLocaleICU) { + moz_free(mLocaleICU); + mLocaleICU = nullptr; + } + } else { + if (mBuffer) { + moz_free(mBuffer); + mBuffer = nullptr; + } + } +} + +nsresult nsCollationMacUC::ConvertStrength(const int32_t aNSStrength, + UCollationStrength* aICUStrength, + UColAttributeValue* aCaseLevelOut) +{ + NS_ENSURE_ARG_POINTER(aICUStrength); + NS_ENSURE_TRUE((aNSStrength < 4), NS_ERROR_FAILURE); + + UCollationStrength strength = UCOL_DEFAULT; + UColAttributeValue caseLevel = UCOL_OFF; + switch (aNSStrength) { + case kCollationCaseInSensitive: + strength = UCOL_PRIMARY; + break; + case kCollationCaseInsensitiveAscii: + strength = UCOL_SECONDARY; + break; + case kCollationAccentInsenstive: + caseLevel = UCOL_ON; + strength = UCOL_PRIMARY; + break; + case kCollationCaseSensitive: + strength = UCOL_TERTIARY; + break; + default: + NS_WARNING("Bad aNSStrength passed to ConvertStrength."); + return NS_ERROR_FAILURE; + } + + *aICUStrength = strength; + *aCaseLevelOut = caseLevel; + + return NS_OK; +} + +nsresult nsCollationMacUC::StrengthToOptions(const int32_t aStrength, + UCCollateOptions* aOptions) +{ + NS_ENSURE_ARG_POINTER(aOptions); + NS_ENSURE_TRUE((aStrength < 4), NS_ERROR_FAILURE); + // set our default collation options + UCCollateOptions options = kUCCollateStandardOptions | kUCCollatePunctuationSignificantMask; + if (aStrength & kCollationCaseInsensitiveAscii) + options |= kUCCollateCaseInsensitiveMask; + if (aStrength & kCollationAccentInsenstive) + options |= kUCCollateDiacritInsensitiveMask; + *aOptions = options; + return NS_OK; +} + +nsresult nsCollationMacUC::ConvertLocaleICU(nsILocale* aNSLocale, char** aICULocale) +{ + NS_ENSURE_ARG_POINTER(aNSLocale); + NS_ENSURE_ARG_POINTER(aICULocale); + + nsAutoString localeString; + nsresult res = aNSLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeString); + NS_ENSURE_TRUE(NS_SUCCEEDED(res) && !localeString.IsEmpty(), + NS_ERROR_FAILURE); + NS_LossyConvertUTF16toASCII tmp(localeString); + tmp.ReplaceChar('-', '_'); + char* locale = (char*)moz_malloc(tmp.Length() + 1); + if (!locale) { + return NS_ERROR_OUT_OF_MEMORY; + } + strcpy(locale, tmp.get()); + + *aICULocale = locale; + + return NS_OK; +} + +nsresult nsCollationMacUC::ConvertLocale(nsILocale* aNSLocale, LocaleRef* aMacLocale) +{ + NS_ENSURE_ARG_POINTER(aNSLocale); + NS_ENSURE_ARG_POINTER(aMacLocale); + + nsAutoString localeString; + nsresult res = aNSLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeString); + NS_ENSURE_TRUE(NS_SUCCEEDED(res) && !localeString.IsEmpty(), + NS_ERROR_FAILURE); + NS_LossyConvertUTF16toASCII tmp(localeString); + tmp.ReplaceChar('-', '_'); + OSStatus err; + err = ::LocaleRefFromLocaleString(tmp.get(), aMacLocale); + NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE); + + return NS_OK; +} + +nsresult nsCollationMacUC::EnsureCollator(const int32_t newStrength) +{ + NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED); + if (mHasCollator && (mLastStrength == newStrength)) + return NS_OK; + + nsresult res; + res = CleanUpCollator(); + NS_ENSURE_SUCCESS(res, res); + + if (mUseICU) { + NS_ENSURE_TRUE(mLocaleICU, NS_ERROR_NOT_INITIALIZED); + + UErrorCode status; + status = U_ZERO_ERROR; + mCollatorICU = ucol_open(mLocaleICU, &status); + NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE); + + UCollationStrength strength; + UColAttributeValue caseLevel; + res = ConvertStrength(newStrength, &strength, &caseLevel); + NS_ENSURE_SUCCESS(res, res); + + status = U_ZERO_ERROR; + ucol_setAttribute(mCollatorICU, UCOL_STRENGTH, strength, &status); + NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE); + ucol_setAttribute(mCollatorICU, UCOL_CASE_LEVEL, caseLevel, &status); + NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE); + ucol_setAttribute(mCollatorICU, UCOL_ALTERNATE_HANDLING, UCOL_DEFAULT, &status); + NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE); + ucol_setAttribute(mCollatorICU, UCOL_NUMERIC_COLLATION, UCOL_OFF, &status); + NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE); + ucol_setAttribute(mCollatorICU, UCOL_NORMALIZATION_MODE, UCOL_ON, &status); + NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE); + ucol_setAttribute(mCollatorICU, UCOL_CASE_FIRST, UCOL_DEFAULT, &status); + NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE); + } else { + OSStatus err; + UCCollateOptions newOptions; + res = StrengthToOptions(newStrength, &newOptions); + NS_ENSURE_SUCCESS(res, res); + + LocaleOperationVariant opVariant = 0; // default variant for now + err = ::UCCreateCollator(mLocale, opVariant, newOptions, &mCollator); + NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE); + } + + mHasCollator = true; + + mLastStrength = newStrength; + return NS_OK; +} + +nsresult nsCollationMacUC::CleanUpCollator(void) +{ + if (mHasCollator) { + if (mUseICU) { + ucol_close(mCollatorICU); + mHasCollator = false; + } else { + OSStatus err = ::UCDisposeCollator(&mCollator); + mHasCollator = false; + NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE); + } + } + + return NS_OK; +} + +NS_IMETHODIMP nsCollationMacUC::Initialize(nsILocale* locale) +{ + NS_ENSURE_TRUE((!mInit), NS_ERROR_ALREADY_INITIALIZED); + nsCOMPtr appLocale; + + nsresult rv; + if (!locale) { + nsCOMPtr localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale)); + NS_ENSURE_SUCCESS(rv, rv); + locale = appLocale; + } + + if (mUseICU) { + rv = ConvertLocaleICU(locale, &mLocaleICU); + } else { + rv = ConvertLocale(locale, &mLocale); + } + NS_ENSURE_SUCCESS(rv, rv); + + mInit = true; + return NS_OK; +} + +NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(int32_t strength, const nsAString& stringIn, + uint8_t** key, uint32_t* outLen) +{ + NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED); + NS_ENSURE_ARG_POINTER(key); + NS_ENSURE_ARG_POINTER(outLen); + + nsresult res = EnsureCollator(strength); + NS_ENSURE_SUCCESS(res, res); + + uint32_t stringInLen = stringIn.Length(); + + if (mUseICU) { + const UChar* str = (const UChar*)PromiseFlatString(stringIn).get(); + + int32_t keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, nullptr, 0); + NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE); + + // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc. + uint8_t* newKey = (uint8_t*)PR_Malloc(keyLength + 1); + if (!newKey) { + return NS_ERROR_OUT_OF_MEMORY; + } + + keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, newKey, keyLength + 1); + NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE); + + *key = newKey; + *outLen = keyLength; + + return NS_OK; + } + + uint32_t maxKeyLen = (1 + stringInLen) * kCollationValueSizeFactor * sizeof(UCCollationValue); + if (maxKeyLen > mBufferLen) { + uint32_t newBufferLen = mBufferLen; + do { + newBufferLen *= 2; + } while (newBufferLen < maxKeyLen); + void* newBuffer = moz_malloc(newBufferLen); + if (!newBuffer) { + return NS_ERROR_OUT_OF_MEMORY; + } + + if (mBuffer) { + moz_free(mBuffer); + mBuffer = nullptr; + } + mBuffer = newBuffer; + mBufferLen = newBufferLen; + } + + ItemCount actual; + OSStatus err = ::UCGetCollationKey(mCollator, (const UniChar*) PromiseFlatString(stringIn).get(), + (UniCharCount) stringInLen, + (ItemCount) (mBufferLen / sizeof(UCCollationValue)), + &actual, (UCCollationValue *)mBuffer); + NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE); + + uint32_t keyLength = actual * sizeof(UCCollationValue); + // Since key is freed elsewhere with PR_Free, allocate with PR_Malloc. + void* newKey = PR_Malloc(keyLength); + if (!newKey) { + return NS_ERROR_OUT_OF_MEMORY; + } + + memcpy(newKey, mBuffer, keyLength); + *key = (uint8_t *)newKey; + *outLen = keyLength; + + return NS_OK; +} + +NS_IMETHODIMP nsCollationMacUC::CompareString(int32_t strength, const nsAString& string1, + const nsAString& string2, int32_t* result) +{ + NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED); + NS_ENSURE_ARG_POINTER(result); + *result = 0; + + nsresult res = EnsureCollator(strength); + NS_ENSURE_SUCCESS(res, res); + + if (mUseICU) { + UCollationResult uresult; + uresult = ucol_strcoll(mCollatorICU, + (const UChar*)PromiseFlatString(string1).get(), string1.Length(), + (const UChar*)PromiseFlatString(string2).get(), string2.Length()); + int32_t res; + switch (uresult) { + case UCOL_LESS: res = -1; break; + case UCOL_EQUAL: res = 0; break; + case UCOL_GREATER: res = 1; break; + default: MOZ_CRASH("ucol_strcoll returned bad UCollationResult"); + } + *result = res; + return NS_OK; + } + + *result = 0; + + OSStatus err; + err = ::UCCompareText(mCollator, + (const UniChar *) PromiseFlatString(string1).get(), (UniCharCount) string1.Length(), + (const UniChar *) PromiseFlatString(string2).get(), (UniCharCount) string2.Length(), + nullptr, (SInt32*) result); + + NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE); + return NS_OK; +} + +NS_IMETHODIMP nsCollationMacUC::CompareRawSortKey(const uint8_t* key1, uint32_t len1, + const uint8_t* key2, uint32_t len2, + int32_t* result) +{ + NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED); + NS_ENSURE_ARG_POINTER(key1); + NS_ENSURE_ARG_POINTER(key2); + NS_ENSURE_ARG_POINTER(result); + *result = 0; + + if (mUseICU) { + int32_t tmpResult = strcmp((const char*)key1, (const char*)key2); + int32_t res; + if (tmpResult < 0) { + res = -1; + } else if (tmpResult > 0) { + res = 1; + } else { + res = 0; + } + *result = res; + return NS_OK; + } + + OSStatus err; + err = ::UCCompareCollationKeys((const UCCollationValue*) key1, (ItemCount) len1, + (const UCCollationValue*) key2, (ItemCount) len2, + nullptr, (SInt32*) result); + + NS_ENSURE_TRUE((err == noErr), NS_ERROR_FAILURE); + + return NS_OK; +} + +} /* namespace mailnews */ diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationMacUC.h thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationMacUC.h --- thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationMacUC.h 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationMacUC.h 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef mailnews_nsCollationMacUC_h_ +#define mailnews_nsCollationMacUC_h_ + +#include "nsICollation.h" +#include "nsCollation.h" +#include "mozilla/Attributes.h" +#include "unicode/ucol.h" +#include + +namespace mailnews { + +// Maximum number of characters for a buffer to remember +// the generated collation key. +const uint32_t kCacheSize = 128; +// According to the documentation, the length of the key should typically be +// at least 5 * textLength, but 6* would be safer. +const uint32_t kCollationValueSizeFactor = 6; + +class nsCollationMacUC MOZ_FINAL : public nsICollation { + +public: + nsCollationMacUC(); + ~nsCollationMacUC(); + + // nsISupports interface + NS_DECL_ISUPPORTS + + // nsICollation interface + NS_DECL_NSICOLLATION + +protected: + nsresult ConvertLocaleICU(nsILocale* aNSLocale, char** aICULocale); + nsresult ConvertLocale(nsILocale* aNSLocale, LocaleRef* aMacLocale); + nsresult ConvertStrength(const int32_t aStrength, + UCollationStrength* aStrengthOut, + UColAttributeValue* aCaseLevelOut); + nsresult StrengthToOptions(const int32_t aStrength, + UCCollateOptions* aOptions); + nsresult EnsureCollator(const int32_t newStrength); + nsresult CleanUpCollator(void); + +private: + bool mInit; + bool mHasCollator; + char* mLocaleICU; + LocaleRef mLocale; + int32_t mLastStrength; + UCollator* mCollatorICU; + CollatorRef mCollator; + void *mBuffer; // temporary buffer to generate collation keys + uint32_t mBufferLen; // byte length of buffer + bool mUseICU; +}; + +} /* namespace mailnews */ + +#endif /* mailnews_nsCollationMacUC_h_ */ diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationRegistrar.cpp thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationRegistrar.cpp --- thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationRegistrar.cpp 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationRegistrar.cpp 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,82 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsCollationCID.h" +#include "nsCollationRegistrar.h" +#include "nsFixedCollationMacUCFactory.h" +#include "nsIComponentRegistrar.h" +#include "nsILocaleService.h" +#include "nsServiceManagerUtils.h" +#include "nsString.h" + +NS_IMPL_ISUPPORTS(nsCollationRegistrar, nsIObserver) + +nsresult nsCollationRegistrar::IsJapanese(bool* isJapanese) +{ + *isJapanese = false; + + nsresult rv; + nsCOMPtr localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr systemLocale; + rv = localeService->GetSystemLocale(getter_AddRefs(systemLocale)); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString localeString; + rv = systemLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeString); + NS_ENSURE_SUCCESS(rv, rv); + + if (localeString.Length() >= 2 && + localeString[0] == 'j' && localeString[1] == 'a') { + *isJapanese = true; + } + + return NS_OK; +} + +nsresult nsCollationRegistrar::Register() +{ + nsresult rv; + nsCOMPtr registrar; + rv = NS_GetComponentRegistrar(getter_AddRefs(registrar)); + NS_ENSURE_SUCCESS(rv, rv); + + // We must register fixed nsCollationMacUC after original one. + bool registered; + rv = registrar->IsContractIDRegistered(NS_COLLATION_CONTRACTID, ®istered); + NS_ENSURE_SUCCESS(rv, rv); + NS_ENSURE_TRUE(registered, NS_ERROR_UNEXPECTED); + + nsCOMPtr originalFactory; + originalFactory = do_GetClassObject(NS_COLLATION_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + rv = registrar->UnregisterFactory(NS_COLLATION_CID, originalFactory); + NS_ENSURE_SUCCESS(rv, rv); + + nsIFactory* fixedFactory = new nsFixedCollationMacUCFactory(); + NS_ENSURE_TRUE(fixedFactory, NS_ERROR_OUT_OF_MEMORY); + return registrar->RegisterFactory(NS_COLLATION_CID, "Fixed nsCollationMacUC", + NS_COLLATION_CONTRACTID, fixedFactory); +} + +NS_IMETHODIMP nsCollationRegistrar::Observe(nsISupports* aSubject, + const char* aTopic, + const char16_t* aData) +{ + if (strcmp(aTopic, NS_XPCOM_STARTUP_CATEGORY) == 0) { + nsresult rv; + bool isJapanese = false; + rv = IsJapanese(&isJapanese); + NS_ENSURE_SUCCESS(rv, rv); + if (isJapanese) { + rv = Register(); + NS_ENSURE_SUCCESS(rv, rv); + } + } + + return NS_OK; +} + diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationRegistrar.h thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationRegistrar.h --- thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationRegistrar.h 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationRegistrar.h 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef _nsCollationRegistrar_h_ +#define _nsCollationRegistrar_h_ + +#include "nsIObserver.h" + +// {BA495E08-7255-46C6-9DED-4A9D434349EB} +#define NS_COLLATION_REGISTRAR_CID \ +{ 0xba495e08, 0x7255, 0x46c6, \ +{ 0x9d, 0xed, 0x4a, 0x9d, 0x43, 0x43, 0x49, 0xeb } } + +#define NS_COLLATION_REGISTRAR_CONTRACTID \ +"@mozilla.org/messenger/collation-registrar;1" + +class nsCollationRegistrar MOZ_FINAL : public nsIObserver { + ~nsCollationRegistrar() {} + + nsresult IsJapanese(bool* out); + nsresult Register(); +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + nsCollationRegistrar() {} +}; + +#endif /* _nsCollationRegistrar_h_ */ diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationRegistrarModule.cpp thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationRegistrarModule.cpp --- thunderbird-31.3.0+build1/mailnews/intl/mac/nsCollationRegistrarModule.cpp 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/nsCollationRegistrarModule.cpp 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "mozilla/ModuleUtils.h" +#include "nsCollationRegistrar.h" +#include "nsID.h" +#include "nsXPCOM.h" + +NS_GENERIC_FACTORY_CONSTRUCTOR(nsCollationRegistrar) + +NS_DEFINE_NAMED_CID(NS_COLLATION_REGISTRAR_CID); + +static const mozilla::Module::CategoryEntry kCollationRegistrarCategories[] = { + { NS_XPCOM_STARTUP_CATEGORY, "nsCollationRegistrar", NS_COLLATION_REGISTRAR_CONTRACTID }, + { nullptr } +}; + +const mozilla::Module::CIDEntry kCollationRegistrarCIDs[] = { + { &kNS_COLLATION_REGISTRAR_CID, false, nullptr, nsCollationRegistrarConstructor }, + { nullptr } +}; + +const mozilla::Module::ContractIDEntry kCollationRegistrarContracts[] = { + { NS_COLLATION_REGISTRAR_CONTRACTID, &kNS_COLLATION_REGISTRAR_CID }, + { nullptr } +}; + +static const mozilla::Module kCollationRegistrarModule = { + mozilla::Module::kVersion, + kCollationRegistrarCIDs, + kCollationRegistrarContracts, + kCollationRegistrarCategories +}; + +NSMODULE_DEFN(nsCollationRegistrar) = &kCollationRegistrarModule; diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.cpp thunderbird-31.4.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.cpp --- thunderbird-31.3.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.cpp 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.cpp 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,26 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsCollationMacUC.h" +#include "nsFixedCollationMacUCFactory.h" +#include "nsICollation.h" + +NS_IMPL_ISUPPORTS(nsFixedCollationMacUCFactory, nsIFactory) + +NS_IMETHODIMP nsFixedCollationMacUCFactory::CreateInstance(nsISupports* aOuter, + const nsID& aIID, + void** aResult) +{ + NS_ENSURE_NO_AGGREGATION(aOuter); + + nsCOMPtr instance = new mailnews::nsCollationMacUC(); + NS_ENSURE_TRUE(instance, NS_ERROR_OUT_OF_MEMORY); + return instance->QueryInterface(aIID, aResult); +} + +NS_IMETHODIMP nsFixedCollationMacUCFactory::LockFactory(bool aVal) +{ + return NS_OK; +} diff -Nru thunderbird-31.3.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.h thunderbird-31.4.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.h --- thunderbird-31.3.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.h 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/mac/nsFixedCollationMacUCFactory.h 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,22 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef _nsFixedCollationMacUCFactory_h_ +#define _nsFixedCollationMacUCFactory_h_ + +#include "nsIFactory.h" + +class nsFixedCollationMacUCFactory MOZ_FINAL : public nsIFactory { + ~nsFixedCollationMacUCFactory() {} +public: + NS_DECL_ISUPPORTS + nsFixedCollationMacUCFactory() {} + + NS_IMETHOD CreateInstance(nsISupports *aOuter, const nsIID &aIID, + void **aResult); + NS_IMETHOD LockFactory(bool aLock); +}; + +#endif /* _nsFixedCollationMacUCFactory_h_ */ diff -Nru thunderbird-31.3.0+build1/mailnews/intl/moz.build thunderbird-31.4.0+build1/mailnews/intl/moz.build --- thunderbird-31.3.0+build1/mailnews/intl/moz.build 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/moz.build 2015-01-12 17:29:34.000000000 +0000 @@ -4,6 +4,9 @@ # 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/. +if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa': + DIRS += ['mac'] + UNIFIED_SOURCES += [ 'nsMUTF7ToUnicode.cpp', 'nsUnicodeToMUTF7.cpp', diff -Nru thunderbird-31.3.0+build1/mailnews/intl/test/unit/test_collation_mac_icu.js thunderbird-31.4.0+build1/mailnews/intl/test/unit/test_collation_mac_icu.js --- thunderbird-31.3.0+build1/mailnews/intl/test/unit/test_collation_mac_icu.js 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/test/unit/test_collation_mac_icu.js 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,110 @@ +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); + +function check_sort() { + var input = [ + "Argentina", + "Oerlikon", + "Offenbach", + "Sverige", + "Vaticano", + "Zimbabwe", + "la France", + "¡viva España!", + "Österreich", + "中国", + "日本", + "한국", + ]; + + function test(locale, expected) { + var localeSvc = Cc["@mozilla.org/intl/nslocaleservice;1"]. + getService(Ci.nsILocaleService); + var collator = Cc["@mozilla.org/intl/collation-factory;1"]. + createInstance(Ci.nsICollationFactory). + CreateCollation(localeSvc.newLocale(locale)); + var strength = Ci.nsICollation.kCollationStrengthDefault; + var actual = input.sort((x, y) => collator.compareString(strength, x,y)); + do_check_eq(JSON.stringify(actual), JSON.stringify(expected)); + } + + // Locale en-US; default options. + test("en-US", [ + "¡viva España!", + "Argentina", + "la France", + "Oerlikon", + "Offenbach", + "Österreich", + "Sverige", + "Vaticano", + "Zimbabwe", + "한국", + "中国", + "日本", + ]); + + // Locale sv-SE; default options. + // Swedish treats "Ö" as a separate character, which sorts after "Z". + test("sv-SE", [ + "¡viva España!", + "Argentina", + "la France", + "Oerlikon", + "Offenbach", + "Sverige", + "Vaticano", + "Zimbabwe", + "Österreich", + "한국", + "中国", + "日本", + ]); + + // Locale de-DE; default options. + // In German standard sorting, umlauted characters are treated as variants + // of their base characters: ä ≅ a, ö ≅ o, ü ≅ u. + test("de-DE", [ + "¡viva España!", + "Argentina", + "la France", + "Oerlikon", + "Offenbach", + "Österreich", + "Sverige", + "Vaticano", + "Zimbabwe", + "한국", + "中国", + "日本", + ]); +} + +function test_default() { + Services.prefs.clearUserPref("intl.collation.mac.use_icu"); + check_sort(); +} + +function test_ICU() { + Services.prefs.setBoolPref("intl.collation.mac.use_icu", true); + check_sort(); +} + +function test_CoreServices() { + Services.prefs.setBoolPref("intl.collation.mac.use_icu", false); + check_sort(); +} + +function run_test() +{ + if (Services.sysinfo.getProperty("arch") == "x86") { + test_default(); + } + test_ICU(); + if (Services.sysinfo.getProperty("arch") == "x86") { + test_CoreServices(); + } + + Services.prefs.clearUserPref("intl.collation.mac.use_icu"); +} diff -Nru thunderbird-31.3.0+build1/mailnews/intl/test/unit/test_collation_registrar.js thunderbird-31.4.0+build1/mailnews/intl/test/unit/test_collation_registrar.js --- thunderbird-31.3.0+build1/mailnews/intl/test/unit/test_collation_registrar.js 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/test/unit/test_collation_registrar.js 2015-01-12 17:29:34.000000000 +0000 @@ -0,0 +1,29 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; +const Cr = Components.results; +const Cm = Components.manager; + +function checkRegistrar() +{ + var localeService = Cc["@mozilla.org/intl/nslocaleservice;1"]. + getService(Ci.nsILocaleService); + var systemLocale = localeService.getSystemLocale(); + + var localeSvc = Cc["@mozilla.org/intl/nslocaleservice;1"]. + getService(Ci.nsILocaleService); + var collator = Cc["@mozilla.org/intl/collation-factory;1"]. + createInstance(Ci.nsICollationFactory). + CreateCollation(localeSvc.newLocale("ja-JP")); + var strength = Ci.nsICollation.kCollationStrengthDefault; + + /* nsICollation uses ICU only if System locale starts with "ja". + * U+3042 < than U+0410 on ICU + * U+3042 > than U+0410 on CoreServices */ + do_check_eq(collator.compareString(strength, "\u3042", "\u0410") < 0, + systemLocale.getCategory("NSILOCALE_COLLATE").startsWith("ja")); +} + +function run_test() +{ + checkRegistrar(); +} diff -Nru thunderbird-31.3.0+build1/mailnews/intl/test/unit/xpcshell.ini thunderbird-31.4.0+build1/mailnews/intl/test/unit/xpcshell.ini --- thunderbird-31.3.0+build1/mailnews/intl/test/unit/xpcshell.ini 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/intl/test/unit/xpcshell.ini 2015-01-12 17:29:34.000000000 +0000 @@ -9,3 +9,9 @@ [test_encode_utf-7.js] [test_encode_utf-7_internal.js] [test_bug718500.js] + +[test_collation_mac_icu.js] +run-if = toolkit == "cocoa" + +[test_collation_registrar.js] +run-if = toolkit == "cocoa" diff -Nru thunderbird-31.3.0+build1/mailnews/mailnews.js thunderbird-31.4.0+build1/mailnews/mailnews.js --- thunderbird-31.3.0+build1/mailnews/mailnews.js 2014-11-28 18:56:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mailnews/mailnews.js 2015-01-12 17:29:34.000000000 +0000 @@ -838,3 +838,8 @@ // PgpMime Addon pref("mail.pgpmime.addon_url", "https://addons.mozilla.org/addon/enigmail/"); + +// Use raw ICU instead of CoreServices API in Unicode collation. +#ifdef XP_MACOSX +pref("intl.collation.mac.use_icu", true); +#endif diff -Nru thunderbird-31.3.0+build1/mozilla/browser/app/blocklist.xml thunderbird-31.4.0+build1/mozilla/browser/app/blocklist.xml --- thunderbird-31.3.0+build1/mozilla/browser/app/blocklist.xml 2014-11-28 19:14:16.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/browser/app/blocklist.xml 2015-01-12 17:51:32.000000000 +0000 @@ -1,5 +1,5 @@ - + @@ -55,6 +55,12 @@ + + + + + + @@ -115,6 +121,12 @@ + + + + + + @@ -133,6 +145,14 @@ + + + + + browser.startup.homepage + browser.search.defaultenginename + + @@ -255,12 +275,6 @@ - - - - - - @@ -307,6 +321,12 @@ + + + + + + @@ -439,6 +459,15 @@ + + + + + + + + + @@ -761,12 +790,10 @@ - + - browser.startup.homepage - browser.search.defaultenginename @@ -851,6 +878,14 @@ + + + + + browser.startup.homepage + browser.search.defaultenginename + + @@ -1561,6 +1596,14 @@ + + + + + browser.startup.homepage + browser.search.defaultenginename + + @@ -1615,6 +1658,12 @@ + + + + + + @@ -2701,6 +2750,18 @@ + + + https://get.adobe.com/flashplayer/ + + + + https://get.adobe.com/flashplayer/ + + + + https://get.adobe.com/flashplayer/ + diff -Nru thunderbird-31.3.0+build1/mozilla/browser/base/content/browser.js thunderbird-31.4.0+build1/mozilla/browser/base/content/browser.js --- thunderbird-31.3.0+build1/mozilla/browser/base/content/browser.js 2014-11-28 19:14:16.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/browser/base/content/browser.js 2015-01-12 17:51:17.000000000 +0000 @@ -809,6 +809,7 @@ gHistorySwipeAnimation.init(); if (window.opener && !window.opener.closed && + window.opener.document.documentURIObject.schemeIs("chrome") && PrivateBrowsingUtils.isWindowPrivate(window) == PrivateBrowsingUtils.isWindowPrivate(window.opener)) { let openerSidebarBox = window.opener.document.getElementById("sidebar-box"); // If the opener had a sidebar, open the same sidebar in our window. diff -Nru thunderbird-31.3.0+build1/mozilla/browser/components/search/test/browser_google_behavior.js thunderbird-31.4.0+build1/mozilla/browser/components/search/test/browser_google_behavior.js --- thunderbird-31.3.0+build1/mozilla/browser/components/search/test/browser_google_behavior.js 2014-11-28 19:14:17.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/browser/components/search/test/browser_google_behavior.js 2015-01-12 17:51:17.000000000 +0000 @@ -7,52 +7,14 @@ "use strict"; -const BROWSER_SEARCH_PREF = "browser.search."; - -const MOZ_PARAM_LOCALE = /\{moz:locale\}/g; -const MOZ_PARAM_DIST_ID = /\{moz:distributionID\}/g; -const MOZ_PARAM_OFFICIAL = /\{moz:official\}/g; - -let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime); -// Custom search parameters -const MOZ_OFFICIAL = runtime.isOfficialBranding ? "official" : "unofficial"; - -var google_client; -switch (runtime.defaultUpdateChannel) { -case "beta": - google_client = "firefox-beta"; - break; -case "aurora": - google_client = "firefox-aurora"; - break; -case "nightly": - google_client = "firefox-nightly"; - break; -default: - google_client = "firefox-a"; - break; -} - -const GOOGLE_CLIENT = google_client; -const MOZ_DISTRIBUTION_ID = runtime.distributionID; - function test() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google is installed"); - is(Services.search.defaultEngine, engine, "Check that Google is the default search engine"); - - let distributionID; - try { - distributionID = Services.prefs.getCharPref(BROWSER_SEARCH_PREF + "distributionID"); - } catch (ex) { - distributionID = MOZ_DISTRIBUTION_ID; - } + let previouslySelectedEngine = Services.search.currentEngine; + Services.search.currentEngine = engine; - let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&aq=t&rls={moz:distributionID}:{moz:locale}:{moz:official}&client=" + GOOGLE_CLIENT; - base = base.replace(MOZ_PARAM_LOCALE, getLocale()); - base = base.replace(MOZ_PARAM_DIST_ID, distributionID); - base = base.replace(MOZ_PARAM_OFFICIAL, MOZ_OFFICIAL); + let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"; let url; @@ -66,7 +28,7 @@ var gTests = [ { name: "context menu search", - searchURL: base + "&channel=rcs", + searchURL: base, run: function () { // Simulate a contextmenu search // FIXME: This is a bit "low-level"... @@ -75,7 +37,7 @@ }, { name: "keyword search", - searchURL: base + "&channel=fflb", + searchURL: base, run: function () { gURLBar.value = "? foo"; gURLBar.focus(); @@ -84,7 +46,7 @@ }, { name: "search bar search", - searchURL: base + "&channel=sb", + searchURL: base, run: function () { let sb = BrowserSearch.searchBar; sb.focus(); @@ -97,7 +59,7 @@ }, { name: "new tab search", - searchURL: base + "&channel=nts", + searchURL: base, run: function () { function doSearch(doc) { // Re-add the listener, and perform a search @@ -141,7 +103,7 @@ }, { name: "home page search", - searchURL: base + "&channel=np&source=hp", + searchURL: base, run: function () { // Bug 992270: Ignore uncaught about:home exceptions (related to snippets from IndexedDB) ignoreAllUncaughtExceptions(true); @@ -216,6 +178,7 @@ registerCleanupFunction(function () { gBrowser.removeProgressListener(listener); gBrowser.removeTab(tab); + Services.search.currentEngine = previouslySelectedEngine; }); tab.linkedBrowser.addEventListener("load", function load() { diff -Nru thunderbird-31.3.0+build1/mozilla/browser/components/search/test/browser_google.js thunderbird-31.4.0+build1/mozilla/browser/components/search/test/browser_google.js --- thunderbird-31.3.0+build1/mozilla/browser/components/search/test/browser_google.js 2014-11-28 19:14:17.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/browser/components/search/test/browser_google.js 2015-01-12 17:51:17.000000000 +0000 @@ -7,52 +7,11 @@ "use strict"; -const BROWSER_SEARCH_PREF = "browser.search."; - -const MOZ_PARAM_LOCALE = /\{moz:locale\}/g; -const MOZ_PARAM_DIST_ID = /\{moz:distributionID\}/g; -const MOZ_PARAM_OFFICIAL = /\{moz:official\}/g; - -let runtime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime); -// Custom search parameters -const MOZ_OFFICIAL = runtime.isOfficialBranding ? "official" : "unofficial"; - -var google_client; -switch (runtime.defaultUpdateChannel) { -case "beta": - google_client = "firefox-beta"; - break; -case "aurora": - google_client = "firefox-aurora"; - break; -case "nightly": - google_client = "firefox-nightly"; - break; -default: - google_client = "firefox-a"; - break; -} - -const GOOGLE_CLIENT = google_client; -const MOZ_DISTRIBUTION_ID = runtime.distributionID; - function test() { let engine = Services.search.getEngineByName("Google"); ok(engine, "Google"); - is(Services.search.defaultEngine, engine, "Check that Google is the default search engine"); - - let distributionID; - try { - distributionID = Services.prefs.getCharPref(BROWSER_SEARCH_PREF + "distributionID"); - } catch (ex) { - distributionID = MOZ_DISTRIBUTION_ID; - } - - let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8&aq=t&rls={moz:distributionID}:{moz:locale}:{moz:official}&client=" + GOOGLE_CLIENT; - base = base.replace(MOZ_PARAM_LOCALE, getLocale()); - base = base.replace(MOZ_PARAM_DIST_ID, distributionID); - base = base.replace(MOZ_PARAM_OFFICIAL, MOZ_OFFICIAL); + let base = "https://www.google.com/search?q=foo&ie=utf-8&oe=utf-8"; let url; @@ -60,15 +19,15 @@ url = engine.getSubmission("foo").uri.spec; is(url, base, "Check search URL for 'foo'"); url = engine.getSubmission("foo", null, "contextmenu").uri.spec; - is(url, base + "&channel=rcs", "Check context menu search URL for 'foo'"); + is(url, base, "Check context menu search URL for 'foo'"); url = engine.getSubmission("foo", null, "keyword").uri.spec; - is(url, base + "&channel=fflb", "Check keyword search URL for 'foo'"); + is(url, base, "Check keyword search URL for 'foo'"); url = engine.getSubmission("foo", null, "searchbar").uri.spec; - is(url, base + "&channel=sb", "Check search bar search URL for 'foo'"); + is(url, base, "Check search bar search URL for 'foo'"); url = engine.getSubmission("foo", null, "homepage").uri.spec; - is(url, base + "&channel=np&source=hp", "Check homepage search URL for 'foo'"); + is(url, base, "Check homepage search URL for 'foo'"); url = engine.getSubmission("foo", null, "newtab").uri.spec; - is(url, base + "&channel=nts", "Check newtab search URL for 'foo'"); + is(url, base, "Check newtab search URL for 'foo'"); // Check search suggestion URL. url = engine.getSubmission("foo", "application/x-suggestions+json").uri.spec; @@ -112,60 +71,8 @@ "value": "utf-8", "purpose": undefined, }, - { - "name": "aq", - "value": "t", - "purpose": undefined, - }, - { - "name": "rls", - "value": "{moz:distributionID}:{moz:locale}:{moz:official}", - "purpose": undefined, - }, - { - "name": "client", - "value": GOOGLE_CLIENT, - "purpose": undefined, - }, - { - "name": "channel", - "value": "rcs", - "purpose": "contextmenu", - }, - { - "name": "channel", - "value": "fflb", - "purpose": "keyword", - }, - { - "name": "channel", - "value": "sb", - "purpose": "searchbar", - }, - { - "name": "channel", - "value": "np", - "purpose": "homepage", - }, - { - "name": "channel", - "value": "nts", - "purpose": "newtab", - }, - { - "name": "source", - "value": "hp", - "purpose": "homepage", - }, ], mozparams: { - "client": { - "name": "client", - "falseValue": "firefox", - "trueValue": GOOGLE_CLIENT, - "condition": "defaultEngine", - "mozparam": true, - }, }, }, { diff -Nru thunderbird-31.3.0+build1/mozilla/browser/config/version.txt thunderbird-31.4.0+build1/mozilla/browser/config/version.txt --- thunderbird-31.3.0+build1/mozilla/browser/config/version.txt 2014-11-28 19:14:32.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/browser/config/version.txt 2015-01-12 17:51:32.000000000 +0000 @@ -1 +1 @@ -31.2.1esrpre +31.3.0esr diff -Nru thunderbird-31.3.0+build1/mozilla/browser/locales/en-US/searchplugins/google.xml thunderbird-31.4.0+build1/mozilla/browser/locales/en-US/searchplugins/google.xml --- thunderbird-31.3.0+build1/mozilla/browser/locales/en-US/searchplugins/google.xml 2014-11-28 19:14:18.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/browser/locales/en-US/searchplugins/google.xml 2015-01-12 17:51:18.000000000 +0000 @@ -14,23 +14,6 @@ - - -#if MOZ_UPDATE_CHANNEL == beta - -#elif MOZ_UPDATE_CHANNEL == aurora - -#elif MOZ_UPDATE_CHANNEL == nightly - -#else - -#endif - - - - - - diff -Nru thunderbird-31.3.0+build1/mozilla/config/milestone.txt thunderbird-31.4.0+build1/mozilla/config/milestone.txt --- thunderbird-31.3.0+build1/mozilla/config/milestone.txt 2014-11-28 19:14:32.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/config/milestone.txt 2015-01-12 17:51:32.000000000 +0000 @@ -10,4 +10,4 @@ # hardcoded milestones in the tree from these two files. #-------------------------------------------------------- -31.3.0 +31.4.0 diff -Nru thunderbird-31.3.0+build1/mozilla/content/base/src/nsScriptLoader.cpp thunderbird-31.4.0+build1/mozilla/content/base/src/nsScriptLoader.cpp --- thunderbird-31.3.0+build1/mozilla/content/base/src/nsScriptLoader.cpp 2014-11-28 19:14:19.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/content/base/src/nsScriptLoader.cpp 2015-01-12 17:51:20.000000000 +0000 @@ -812,7 +812,12 @@ { MOZ_ASSERT(NS_IsMainThread()); - nsresult rv = mLoader->ProcessOffThreadRequest(mRequest, &mToken); + // We want these to be dropped on the main thread, once we return from this + // function. + nsRefPtr request = mRequest.forget(); + nsRefPtr loader = mLoader.forget(); + + nsresult rv = loader->ProcessOffThreadRequest(request, &mToken); if (mToken) { // The result of the off thread parse was not actually needed to process diff -Nru thunderbird-31.3.0+build1/mozilla/dom/base/Navigator.cpp thunderbird-31.4.0+build1/mozilla/dom/base/Navigator.cpp --- thunderbird-31.3.0+build1/mozilla/dom/base/Navigator.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/dom/base/Navigator.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -1265,6 +1265,9 @@ principal, true); + rv = cors->Init(channel, true); + NS_ENSURE_SUCCESS(rv, false); + // Start a preflight if cross-origin and content type is not whitelisted rv = secMan->CheckSameOriginURI(documentURI, uri, false); bool crossOrigin = NS_FAILED(rv); diff -Nru thunderbird-31.3.0+build1/mozilla/dom/base/nsGlobalWindow.cpp thunderbird-31.4.0+build1/mozilla/dom/base/nsGlobalWindow.cpp --- thunderbird-31.3.0+build1/mozilla/dom/base/nsGlobalWindow.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/dom/base/nsGlobalWindow.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -12521,8 +12521,18 @@ nsCOMPtr sourceWindow; JSContext* topCx = nsContentUtils::GetCurrentJSContext(); if (topCx) { - sourceWindow = do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(topCx)); + nsCOMPtr entryWindow = + do_QueryInterface(nsJSUtils::GetDynamicScriptGlobal(topCx)); + if (entryWindow) { + nsIPrincipal* entryPrin = + static_cast(entryWindow.get())->GetPrincipal(); + nsIPrincipal* subjectPrin = nsContentUtils::GetSubjectPrincipal(); + if (subjectPrin->SubsumesConsideringDomain(entryPrin)) { + sourceWindow = entryWindow; + } + } } + if (!sourceWindow) { sourceWindow = this; } diff -Nru thunderbird-31.3.0+build1/mozilla/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs thunderbird-31.4.0+build1/mozilla/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs --- thunderbird-31.3.0+build1/mozilla/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/dom/tests/mochitest/beacon/beacon-originheader-handler.sjs 2015-01-12 17:51:24.000000000 +0000 @@ -0,0 +1,41 @@ +/* + * TestSever customized specifically for the needs of: + * Bug 1080987 - navigator.sendBeacon() needs to sent origin header + */ + +function handleRequest(request, response) +{ + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/plain", false); + + // case XHR-REQUEST: the xhr-request tries to query the + // stored header from the beacon request. + if (request.queryString == "queryheader") { + var header = getState("originHeader"); + // if the beacon already stored the header - return. + if (header) { + response.write(header); + setState("originHeader", ""); + return; + } + // otherwise wait for the beacon request + response.processAsync(); + setObjectState("xhr-response", response); + return; + } + + // case BEACON-REQUEST: get the beacon header and + // store the header on the server. + var header = request.getHeader("origin"); + setState("originHeader", header); + + // if there is an xhr-request waiting, return the header now. + getObjectState("xhr-response", function(xhrResponse) { + if (!xhrResponse) { + return; + } + setState("originHeader", ""); + xhrResponse.write(header); + xhrResponse.finish(); + }); +} diff -Nru thunderbird-31.3.0+build1/mozilla/dom/tests/mochitest/beacon/mochitest.ini thunderbird-31.4.0+build1/mozilla/dom/tests/mochitest/beacon/mochitest.ini --- thunderbird-31.3.0+build1/mozilla/dom/tests/mochitest/beacon/mochitest.ini 2014-11-28 19:14:24.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/dom/tests/mochitest/beacon/mochitest.ini 2015-01-12 17:51:24.000000000 +0000 @@ -2,8 +2,10 @@ skip-if = buildapp == 'b2g' || e10s support-files = beacon-frame.html beacon-handler.sjs + beacon-originheader-handler.sjs [test_beacon.html] [test_beaconFrame.html] [test_beaconPreflight.html] [test_beaconContentPolicy.html] +[test_beaconOriginHeader.html] diff -Nru thunderbird-31.3.0+build1/mozilla/dom/tests/mochitest/beacon/test_beaconOriginHeader.html thunderbird-31.4.0+build1/mozilla/dom/tests/mochitest/beacon/test_beaconOriginHeader.html --- thunderbird-31.3.0+build1/mozilla/dom/tests/mochitest/beacon/test_beaconOriginHeader.html 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/dom/tests/mochitest/beacon/test_beaconOriginHeader.html 2015-01-12 17:51:24.000000000 +0000 @@ -0,0 +1,64 @@ + + + + Bug 1080987 - navigator.sendBeacon() needs to sent origin header + + + + + +

    + + + + + + diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -3984,25 +3984,18 @@ } void -MacroAssemblerARMCompat::handleFailureWithHandler(void *handler) +MacroAssemblerARMCompat::handleFailureWithHandlerTail(void *handler) { // Reserve space for exception information. int size = (sizeof(ResumeFromException) + 7) & ~7; ma_sub(Imm32(size), sp); ma_mov(sp, r0); - // Ask for an exception handler. + // Call the handler. setupUnalignedABICall(1, r1); passABIArg(r0); callWithABI(handler); - JitCode *excTail = GetIonContext()->runtime->jitRuntime()->getExceptionTail(); - branch(excTail); -} - -void -MacroAssemblerARMCompat::handleFailureWithHandlerTail() -{ Label entryFrame; Label catch_; Label finally; diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.h thunderbird-31.4.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.h 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/arm/MacroAssembler-arm.h 2015-01-12 17:51:22.000000000 +0000 @@ -711,6 +711,9 @@ void jump(Label *label) { as_b(label); } + void jump(JitCode *code) { + branch(code); + } void jump(Register reg) { ma_bx(reg); } @@ -1202,8 +1205,7 @@ void linkExitFrame(); void linkParallelExitFrame(const Register &pt); - void handleFailureWithHandler(void *handler); - void handleFailureWithHandlerTail(); + void handleFailureWithHandlerTail(void *handler); ///////////////////////////////////////////////////////////////// // Common interface. diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/arm/Trampoline-arm.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/arm/Trampoline-arm.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/arm/Trampoline-arm.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/arm/Trampoline-arm.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -928,11 +928,11 @@ } JitCode * -JitRuntime::generateExceptionTailStub(JSContext *cx) +JitRuntime::generateExceptionTailStub(JSContext *cx, void *handler) { MacroAssembler masm; - masm.handleFailureWithHandlerTail(); + masm.handleFailureWithHandlerTail(handler); Linker linker(masm); AutoFlushICache afc("ExceptionTailStub"); diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/CompileInfo.h thunderbird-31.4.0+build1/mozilla/js/src/jit/CompileInfo.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/CompileInfo.h 2014-11-28 19:14:32.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/CompileInfo.h 2015-01-12 17:51:22.000000000 +0000 @@ -305,6 +305,15 @@ return executionMode_ == ParallelExecution; } + bool canOptimizeOutSlot(uint32_t i) const { + if (script()->strict()) + return true; + + // Function.arguments can be used to access all arguments in + // non-strict scripts, so we can't optimize out any arguments. + return !(firstArgSlot() <= i && i - firstArgSlot() < nargs()); + } + private: unsigned nimplicit_; unsigned nargs_; diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/IonAnalysis.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/IonAnalysis.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/IonAnalysis.cpp 2014-11-28 19:14:32.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/IonAnalysis.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -137,6 +137,14 @@ continue; } + // The operand is an uneliminable slot. This currently + // includes argument slots in non-strict scripts (due to being + // observable via Function.arguments). + if (!block->info().canOptimizeOutSlot(uses->index())) { + uses++; + continue; + } + // Store an optimized out magic value in place of all dead // resume point operands. Making any such substitution can in // general alter the interpreter's behavior, even though the @@ -233,18 +241,11 @@ return true; } - // If the Phi is one of the formal argument, and we are using an argument - // object in the function. The phi might be observable after a bailout. - // For inlined frames this is not needed, as they are captured in the inlineResumePoint. - if (fun && info.hasArguments()) { - uint32_t first = info.firstArgSlot(); - if (first <= slot && slot - first < info.nargs()) { - // If arguments obj aliases formals, then the arg slots will never be used. - if (info.argsObjAliasesFormals()) - return false; - return true; - } - } + // The Phi is an uneliminable slot. Currently this includes argument slots + // in non-strict scripts (due to being observable via Function.arguments). + if (fun && !info.canOptimizeOutSlot(slot)) + return true; + return false; } diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/Ion.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/Ion.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/Ion.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/Ion.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -150,6 +150,7 @@ : execAlloc_(nullptr), ionAlloc_(nullptr), exceptionTail_(nullptr), + exceptionTailParallel_(nullptr), bailoutTail_(nullptr), enterJIT_(nullptr), bailoutHandler_(nullptr), @@ -198,10 +199,18 @@ return false; IonSpew(IonSpew_Codegen, "# Emitting exception tail stub"); - exceptionTail_ = generateExceptionTailStub(cx); + + void *handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleException); + void *handlerParallel = JS_FUNC_TO_DATA_PTR(void *, jit::HandleParallelFailure); + + exceptionTail_ = generateExceptionTailStub(cx, handler); if (!exceptionTail_) return false; + exceptionTailParallel_ = generateExceptionTailStub(cx, handlerParallel); + if (!exceptionTailParallel_) + return false; + IonSpew(IonSpew_Codegen, "# Emitting bailout tail stub"); bailoutTail_ = generateBailoutTailStub(cx); if (!bailoutTail_) diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/IonMacroAssembler.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/IonMacroAssembler.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/IonMacroAssembler.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/IonMacroAssembler.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -1030,18 +1030,18 @@ sps_->skipNextReenter(); leaveSPSFrame(); - void *handler; + JitCode *excTail; switch (executionMode) { case SequentialExecution: - handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleException); + excTail = GetIonContext()->runtime->jitRuntime()->getExceptionTail(); break; case ParallelExecution: - handler = JS_FUNC_TO_DATA_PTR(void *, jit::HandleParallelFailure); + excTail = GetIonContext()->runtime->jitRuntime()->getExceptionTailParallel(); break; default: MOZ_ASSUME_UNREACHABLE("No such execution mode"); } - MacroAssemblerSpecific::handleFailureWithHandler(handler); + jump(excTail); // Doesn't actually emit code, but balances the leave() if (sps_) diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/JitCompartment.h thunderbird-31.4.0+build1/mozilla/js/src/jit/JitCompartment.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/JitCompartment.h 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/JitCompartment.h 2015-01-12 17:51:22.000000000 +0000 @@ -153,8 +153,9 @@ // need for explicit interrupt checks. JSC::ExecutableAllocator *ionAlloc_; - // Shared post-exception-handler tail + // Shared exception-handler tail. JitCode *exceptionTail_; + JitCode *exceptionTailParallel_; // Shared post-bailout-handler tail. JitCode *bailoutTail_; @@ -214,7 +215,7 @@ InlineList backedgeList_; private: - JitCode *generateExceptionTailStub(JSContext *cx); + JitCode *generateExceptionTailStub(JSContext *cx, void *handler); JitCode *generateBailoutTailStub(JSContext *cx); JitCode *generateEnterJIT(JSContext *cx, EnterJitType type); JitCode *generateArgumentsRectifier(JSContext *cx, ExecutionMode mode, void **returnAddrOut); @@ -287,6 +288,9 @@ JitCode *getExceptionTail() const { return exceptionTail_; } + JitCode *getExceptionTailParallel() const { + return exceptionTailParallel_; + } JitCode *getBailoutTail() const { return bailoutTail_; diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/LIR.h thunderbird-31.4.0+build1/mozilla/js/src/jit/LIR.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/LIR.h 2014-11-28 19:14:32.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/LIR.h 2015-01-12 17:51:22.000000000 +0000 @@ -1419,6 +1419,10 @@ static bool match(const Value &lhs, const Value &rhs) { return lhs == rhs; } + +#ifdef DEBUG + bool canOptimizeOutIfUnused(); +#endif }; diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -3139,25 +3139,18 @@ } void -MacroAssemblerMIPSCompat::handleFailureWithHandler(void *handler) +MacroAssemblerMIPSCompat::handleFailureWithHandlerTail(void *handler) { // Reserve space for exception information. int size = (sizeof(ResumeFromException) + StackAlignment) & ~(StackAlignment - 1); ma_subu(StackPointer, StackPointer, Imm32(size)); ma_move(a0, StackPointer); // Use a0 since it is a first function argument - // Ask for an exception handler. + // Call the handler. setupUnalignedABICall(1, a1); passABIArg(a0); callWithABI(handler); - JitCode *excTail = GetIonContext()->runtime->jitRuntime()->getExceptionTail(); - branch(excTail); -} - -void -MacroAssemblerMIPSCompat::handleFailureWithHandlerTail() -{ Label entryFrame; Label catch_; Label finally; diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.h thunderbird-31.4.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.h 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/mips/MacroAssembler-mips.h 2015-01-12 17:51:22.000000000 +0000 @@ -481,6 +481,10 @@ as_nop(); } + void jump(JitCode *code) { + branch(code); + } + void neg32(Register reg) { ma_negu(reg, reg); } @@ -842,8 +846,7 @@ void linkExitFrame(); void linkParallelExitFrame(const Register &pt); - void handleFailureWithHandler(void *handler); - void handleFailureWithHandlerTail(); + void handleFailureWithHandlerTail(void *handler); ///////////////////////////////////////////////////////////////// // Common interface. diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/mips/Trampoline-mips.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/mips/Trampoline-mips.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/mips/Trampoline-mips.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/mips/Trampoline-mips.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -960,11 +960,11 @@ JitCode * -JitRuntime::generateExceptionTailStub(JSContext *cx) +JitRuntime::generateExceptionTailStub(JSContext *cx, void *handler) { MacroAssembler masm; - masm.handleFailureWithHandlerTail(); + masm.handleFailureWithHandlerTail(handler); Linker linker(masm); AutoFlushICache afc("ExceptionTailStub"); diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/shared/MacroAssembler-x86-shared.h thunderbird-31.4.0+build1/mozilla/js/src/jit/shared/MacroAssembler-x86-shared.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/shared/MacroAssembler-x86-shared.h 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/shared/MacroAssembler-x86-shared.h 2015-01-12 17:51:22.000000000 +0000 @@ -287,6 +287,9 @@ void jump(Label *label) { jmp(label); } + void jump(JitCode *code) { + jmp(code); + } void jump(RepatchLabel *label) { jmp(label); } diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -287,24 +287,17 @@ } void -MacroAssemblerX64::handleFailureWithHandler(void *handler) +MacroAssemblerX64::handleFailureWithHandlerTail(void *handler) { // Reserve space for exception information. subq(Imm32(sizeof(ResumeFromException)), rsp); movq(rsp, rax); - // Ask for an exception handler. + // Call the handler. setupUnalignedABICall(1, rcx); passABIArg(rax); callWithABI(handler); - JitCode *excTail = GetIonContext()->runtime->jitRuntime()->getExceptionTail(); - jmp(excTail); -} - -void -MacroAssemblerX64::handleFailureWithHandlerTail() -{ Label entryFrame; Label catch_; Label finally; diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.h thunderbird-31.4.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.h 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/x64/MacroAssembler-x64.h 2015-01-12 17:51:22.000000000 +0000 @@ -1288,8 +1288,7 @@ void callWithABI(AsmJSImmPtr imm, MoveOp::Type result = MoveOp::GENERAL); void callWithABI(Address fun, MoveOp::Type result = MoveOp::GENERAL); - void handleFailureWithHandler(void *handler); - void handleFailureWithHandlerTail(); + void handleFailureWithHandlerTail(void *handler); void makeFrameDescriptor(Register frameSizeReg, FrameType type) { shlq(Imm32(FRAMESIZE_SHIFT), frameSizeReg); diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/x64/Trampoline-x64.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/x64/Trampoline-x64.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/x64/Trampoline-x64.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/x64/Trampoline-x64.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -785,11 +785,11 @@ } JitCode * -JitRuntime::generateExceptionTailStub(JSContext *cx) +JitRuntime::generateExceptionTailStub(JSContext *cx, void *handler) { MacroAssembler masm; - masm.handleFailureWithHandlerTail(); + masm.handleFailureWithHandlerTail(handler); Linker linker(masm); JitCode *code = linker.newCode(cx, JSC::OTHER_CODE); diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -281,24 +281,17 @@ } void -MacroAssemblerX86::handleFailureWithHandler(void *handler) +MacroAssemblerX86::handleFailureWithHandlerTail(void *handler) { // Reserve space for exception information. subl(Imm32(sizeof(ResumeFromException)), esp); movl(esp, eax); - // Ask for an exception handler. + // Call the handler. setupUnalignedABICall(1, ecx); passABIArg(eax); callWithABI(handler); - JitCode *excTail = GetIonContext()->runtime->jitRuntime()->getExceptionTail(); - jmp(excTail); -} - -void -MacroAssemblerX86::handleFailureWithHandlerTail() -{ Label entryFrame; Label catch_; Label finally; diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.h thunderbird-31.4.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.h --- thunderbird-31.3.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.h 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/x86/MacroAssembler-x86.h 2015-01-12 17:51:22.000000000 +0000 @@ -1086,8 +1086,7 @@ void callWithABI(const Address &fun, MoveOp::Type result = MoveOp::GENERAL); // Used from within an Exit frame to handle a pending exception. - void handleFailureWithHandler(void *handler); - void handleFailureWithHandlerTail(); + void handleFailureWithHandlerTail(void *handler); void makeFrameDescriptor(Register frameSizeReg, FrameType type) { shll(Imm32(FRAMESIZE_SHIFT), frameSizeReg); diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit/x86/Trampoline-x86.cpp thunderbird-31.4.0+build1/mozilla/js/src/jit/x86/Trampoline-x86.cpp --- thunderbird-31.3.0+build1/mozilla/js/src/jit/x86/Trampoline-x86.cpp 2014-11-28 19:14:23.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit/x86/Trampoline-x86.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -827,11 +827,11 @@ } JitCode * -JitRuntime::generateExceptionTailStub(JSContext *cx) +JitRuntime::generateExceptionTailStub(JSContext *cx, void *handler) { MacroAssembler masm; - masm.handleFailureWithHandlerTail(); + masm.handleFailureWithHandlerTail(handler); Linker linker(masm); JitCode *code = linker.newCode(cx, JSC::OTHER_CODE); diff -Nru thunderbird-31.3.0+build1/mozilla/js/src/jit-test/tests/debug/optimized-out-01.js thunderbird-31.4.0+build1/mozilla/js/src/jit-test/tests/debug/optimized-out-01.js --- thunderbird-31.3.0+build1/mozilla/js/src/jit-test/tests/debug/optimized-out-01.js 2014-11-28 19:14:32.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/js/src/jit-test/tests/debug/optimized-out-01.js 2015-01-12 17:51:22.000000000 +0000 @@ -25,9 +25,10 @@ } }; - g.eval("" + function f(d, x) { g(d, x); }); + g.eval("" + function f(d, x) { "use strict"; g(d, x); }); g.eval("" + function g(d, x) { + "use strict"; for (var i = 0; i < 200; i++); // Hack to prevent inlining. function inner() { i = 42; }; diff -Nru thunderbird-31.3.0+build1/mozilla/media/libcubeb/src/cubeb_wasapi.cpp thunderbird-31.4.0+build1/mozilla/media/libcubeb/src/cubeb_wasapi.cpp --- thunderbird-31.3.0+build1/mozilla/media/libcubeb/src/cubeb_wasapi.cpp 2014-11-28 19:14:21.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/media/libcubeb/src/cubeb_wasapi.cpp 2015-01-12 17:51:22.000000000 +0000 @@ -365,10 +365,8 @@ assert(padding <= stm->buffer_frame_count); if (stm->draining) { - if (padding == 0) { - stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED); - is_playing = false; - } + stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED); + is_playing = false; continue; } diff -Nru thunderbird-31.3.0+build1/mozilla/mobile/android/base/tests/BaseTest.java thunderbird-31.4.0+build1/mozilla/mobile/android/base/tests/BaseTest.java --- thunderbird-31.3.0+build1/mozilla/mobile/android/base/tests/BaseTest.java 2014-11-28 19:14:16.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/mobile/android/base/tests/BaseTest.java 2015-01-12 17:51:17.000000000 +0000 @@ -172,6 +172,7 @@ boolean success = waitForCondition(new Condition() { @Override public boolean isSatisfied() { + mSolo.waitForView(R.id.url_edit_text); EditText urlEditText = (EditText) mSolo.getView(R.id.url_edit_text); if (urlEditText.isInputMethodTarget()) { return true; diff -Nru thunderbird-31.3.0+build1/mozilla/mobile/android/base/tests/testSearchSuggestions.java thunderbird-31.4.0+build1/mozilla/mobile/android/base/tests/testSearchSuggestions.java --- thunderbird-31.3.0+build1/mozilla/mobile/android/base/tests/testSearchSuggestions.java 2014-11-28 19:14:16.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/mobile/android/base/tests/testSearchSuggestions.java 2015-01-12 17:51:17.000000000 +0000 @@ -53,6 +53,7 @@ } final String query = TEST_QUERY.substring(0, i+1); + mSolo.waitForView(R.id.suggestion_text); boolean success = waitForTest(new BooleanTest() { @Override public boolean test() { diff -Nru thunderbird-31.3.0+build1/mozilla/mobile/android/config/armv6_play_store_version_code.txt thunderbird-31.4.0+build1/mozilla/mobile/android/config/armv6_play_store_version_code.txt --- thunderbird-31.3.0+build1/mozilla/mobile/android/config/armv6_play_store_version_code.txt 2014-11-28 19:14:16.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/mobile/android/config/armv6_play_store_version_code.txt 2015-01-12 17:51:17.000000000 +0000 @@ -1 +1 @@ -2014080004 \ No newline at end of file +2014080005 \ No newline at end of file diff -Nru thunderbird-31.3.0+build1/mozilla/mobile/android/confvars.sh thunderbird-31.4.0+build1/mozilla/mobile/android/confvars.sh --- thunderbird-31.3.0+build1/mozilla/mobile/android/confvars.sh 2014-11-28 19:14:16.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/mobile/android/confvars.sh 2015-01-12 17:51:17.000000000 +0000 @@ -5,7 +5,7 @@ MOZ_APP_BASENAME=Fennec MOZ_APP_VENDOR=Mozilla -MOZ_APP_VERSION=31.2.0esr +MOZ_APP_VERSION=31.3.0esr MOZ_APP_UA_NAME=Firefox MOZ_BRANDING_DIRECTORY=mobile/android/branding/unofficial diff -Nru thunderbird-31.3.0+build1/mozilla/mobile/locales/en-US/searchplugins/google.xml thunderbird-31.4.0+build1/mozilla/mobile/locales/en-US/searchplugins/google.xml --- thunderbird-31.3.0+build1/mozilla/mobile/locales/en-US/searchplugins/google.xml 2014-11-28 19:14:17.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/mobile/locales/en-US/searchplugins/google.xml 2015-01-12 17:51:18.000000000 +0000 @@ -11,9 +11,6 @@ - - -
    https://www.google.com diff -Nru thunderbird-31.3.0+build1/mozilla/netwerk/protocol/http/nsHttpChannel.cpp thunderbird-31.4.0+build1/mozilla/netwerk/protocol/http/nsHttpChannel.cpp --- thunderbird-31.3.0+build1/mozilla/netwerk/protocol/http/nsHttpChannel.cpp 2014-11-28 19:14:18.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/netwerk/protocol/http/nsHttpChannel.cpp 2015-01-12 17:51:18.000000000 +0000 @@ -1237,7 +1237,12 @@ // notify "http-on-examine-response" observers gHttpHandler->OnExamineResponse(this); - SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie)); + // Cookies should not be handled on proxy failure either. + // This would be consolidated with ProcessSecurityHeaders but it should + // happen after OnExamineResponse. + if (!mTransaction->ProxyConnectFailed() && (httpStatus != 407)) { + SetCookie(mResponseHead->PeekHeader(nsHttp::Set_Cookie)); + } // handle unused username and password in url (see bug 232567) if (httpStatus != 401 && httpStatus != 407) { diff -Nru thunderbird-31.3.0+build1/mozilla/netwerk/test/unit/test_auth_proxy.js thunderbird-31.4.0+build1/mozilla/netwerk/test/unit/test_auth_proxy.js --- thunderbird-31.3.0+build1/mozilla/netwerk/test/unit/test_auth_proxy.js 2014-11-28 19:14:18.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/netwerk/test/unit/test_auth_proxy.js 2015-01-12 17:51:19.000000000 +0000 @@ -172,6 +172,12 @@ // If we expect 200, the request should have succeeded do_check_eq(this.expectedCode == 200, request.requestSucceeded); + var cookie = ""; + try { + cookie = request.getRequestHeader("Cookie"); + } catch (e) { } + do_check_eq(cookie, ""); + } catch (e) { do_throw("Unexpected exception: " + e); } @@ -261,6 +267,25 @@ do_test_pending(); } +function test_proxy_407_cookie() { + var chan = makeChan(); + chan.notificationCallbacks = new Requestor(FLAG_RETURN_FALSE, 0); + chan.setRequestHeader("X-Set-407-Cookie", "1", false); + listener.expectedCode = 407; // Proxy Unauthorized + chan.asyncOpen(listener, null); + + do_test_pending(); +} + +function test_proxy_200_cookie() { + var chan = makeChan(); + chan.notificationCallbacks = new Requestor(0, 0); + chan.setRequestHeader("X-Set-407-Cookie", "1", false); + listener.expectedCode = 200; // OK + chan.asyncOpen(listener, null); + do_test_pending(); +} + function test_host_returnfalse() { dump("\ntest: host returnfalse\n"); var chan = makeChan(); @@ -301,6 +326,7 @@ } var tests = [test_proxy_returnfalse, test_proxy_wrongpw, test_all_ok, + test_proxy_407_cookie, test_proxy_200_cookie, test_host_returnfalse, test_host_wrongpw, test_proxy_wrongpw_host_wrongpw, test_proxy_wrongpw_host_returnfalse]; @@ -331,6 +357,9 @@ "Unauthorized by HTTP proxy"); response.setHeader("Proxy-Authenticate", 'Basic realm="' + realm + '"', false); + if (metadata.hasHeader("X-Set-407-Cookie")) { + response.setHeader("Set-Cookie", "chewy", false); + } body = "failed"; response.bodyOutputStream.write(body, body.length); } diff -Nru thunderbird-31.3.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.errors thunderbird-31.4.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.errors --- thunderbird-31.3.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.errors 2014-11-28 19:14:19.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.errors 2015-01-12 17:51:32.000000000 +0000 @@ -1,7 +1,6 @@ admin.google.com: did not receive HSTS header (error ignored - included regardless) adsfund.org: could not connect to host airbnb.com: did not receive HSTS header -api.lookout.com: could not connect to host api.mega.co.nz: could not connect to host api.recurly.com: did not receive HSTS header apis.google.com: did not receive HSTS header (error ignored - included regardless) @@ -13,6 +12,7 @@ bedeta.de: could not connect to host betnet.fr: could not connect to host bigshinylock.minazo.net: could not connect to host +bitfactory.ws: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-esr31-l64-periodicupdate-000/getHSTSPreloadList.js :: processStsHeader :: line 125" data: no] blog.lookout.com: did not receive HSTS header braintreegateway.com: did not receive HSTS header braintreepayments.com: did not receive HSTS header @@ -33,9 +33,11 @@ crowdcurity.com: did not receive HSTS header crypto.is: did not receive HSTS header csawctf.poly.edu: did not receive HSTS header +cybershambles.com: could not connect to host discovery.lookout.com: did not receive HSTS header dl.google.com: did not receive HSTS header (error ignored - included regardless) docs.google.com: did not receive HSTS header (error ignored - included regardless) +download.jitsi.org: did not receive HSTS header drive.google.com: did not receive HSTS header (error ignored - included regardless) dropcam.com: did not receive HSTS header ed.gs: did not receive HSTS header @@ -43,6 +45,7 @@ email.lookout.com: could not connect to host encrypted.google.com: did not receive HSTS header (error ignored - included regardless) epoxate.com: did not receive HSTS header +errors.zenpayroll.com: could not connect to host espra.com: could not connect to host fatzebra.com.au: did not receive HSTS header gamesdepartment.co.uk: did not receive HSTS header @@ -65,6 +68,7 @@ honeytracks.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-esr31-l64-periodicupdate-000/getHSTSPreloadList.js :: processStsHeader :: line 125" data: no] hostedtalkgadget.google.com: did not receive HSTS header (error ignored - included regardless) howrandom.org: could not connect to host +iban.is: could not connect to host inertianetworks.com: did not receive HSTS header intercom.io: did not receive HSTS header iop.intuit.com: max-age too low: 86400 @@ -72,7 +76,9 @@ itriskltd.com: did not receive HSTS header jottit.com: could not connect to host keymaster.lookout.com: did not receive HSTS header +kitsta.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-esr31-l64-periodicupdate-000/getHSTSPreloadList.js :: processStsHeader :: line 125" data: no] kiwiirc.com: max-age too low: 5256000 +klaxn.com: could not connect to host ledgerscope.net: did not receive HSTS header liberty.lavabit.com: could not connect to host lifeguard.aecom.com: max-age too low: 86400 @@ -82,8 +88,8 @@ lumi.do: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-esr31-l64-periodicupdate-000/getHSTSPreloadList.js :: processStsHeader :: line 125" data: no] m.gparent.org: could not connect to host mail.google.com: did not receive HSTS header (error ignored - included regardless) +manage.zenpayroll.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-esr31-l64-periodicupdate-000/getHSTSPreloadList.js :: processStsHeader :: line 125" data: no] market.android.com: did not receive HSTS header (error ignored - included regardless) -markusueberallassetmanagement.de: could not connect to host matteomarescotti.name: could not connect to host mobilethreat.net: could not connect to host mobilethreatnetwork.net: could not connect to host @@ -91,7 +97,6 @@ my.alfresco.com: did not receive HSTS header mydigipass.com: did not receive HSTS header mykolab.com: did not receive HSTS header -neg9.org: did not receive HSTS header neonisi.com: could not connect to host netzpolitik.org: did not receive HSTS header nexth.de: could not connect to host @@ -103,7 +108,7 @@ ottospora.nl: could not connect to host passwordbox.com: did not receive HSTS header payroll.xero.com: max-age too low: 3600 -piratenlogin.de: did not receive HSTS header +piratenlogin.de: could not connect to host platform.lookout.com: could not connect to host play.google.com: did not receive HSTS header (error ignored - included regardless) pressfreedomfoundation.org: did not receive HSTS header @@ -114,8 +119,9 @@ redports.org: could not connect to host riseup.net: did not receive HSTS header rme.li: did not receive HSTS header +roddis.net: did not receive HSTS header sah3.net: could not connect to host -saturngames.co.uk: did not receive HSTS header +saturngames.co.uk: could not connect to host script.google.com: did not receive HSTS header (error ignored - included regardless) security.google.com: did not receive HSTS header (error ignored - included regardless) semenkovich.com: did not receive HSTS header @@ -136,15 +142,20 @@ stocktrade.de: could not connect to host sunshinepress.org: could not connect to host surfeasy.com: did not receive HSTS header -talk.google.com: did not receive HSTS header (error ignored - included regardless) +talk.google.com: could not connect to host +talk.google.com: could not connect to host (error ignored - included regardless) talkgadget.google.com: did not receive HSTS header (error ignored - included regardless) tektoria.de: did not receive HSTS header translate.googleapis.com: did not receive HSTS header (error ignored - included regardless) +unterfrankenclan.de: could not connect to host uprotect.it: could not connect to host +viennan.net: did not receive HSTS header wallet.google.com: did not receive HSTS header (error ignored - included regardless) webmail.mayfirst.org: did not receive HSTS header whonix.org: did not receive HSTS header wiz.biz: did not receive HSTS header +www.airbnb.com: did not receive HSTS header +www.apollo-auto.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-esr31-l64-periodicupdate-000/getHSTSPreloadList.js :: processStsHeader :: line 125" data: no] www.calyxinstitute.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: /builds/slave/m-esr31-l64-periodicupdate-000/getHSTSPreloadList.js :: processStsHeader :: line 125" data: no] www.cueup.com: could not connect to host www.developer.mydigipass.com: could not connect to host @@ -159,7 +170,6 @@ www.neonisi.com: could not connect to host www.paycheckrecords.com: max-age too low: 86400 www.rme.li: did not receive HSTS header -www.roddis.net: did not receive HSTS header www.sandbox.mydigipass.com: could not connect to host www.surfeasy.com: did not receive HSTS header zoo24.de: did not receive HSTS header diff -Nru thunderbird-31.3.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.inc thunderbird-31.4.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.inc --- thunderbird-31.3.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.inc 2014-11-28 19:14:19.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/security/manager/boot/src/nsSTSPreloadList.inc 2015-01-12 17:51:32.000000000 +0000 @@ -8,7 +8,7 @@ /*****************************************************************************/ #include -const PRTime gPreloadListExpirationTime = INT64_C(1427540947947000); +const PRTime gPreloadListExpirationTime = INT64_C(1431169667113000); class nsSTSPreload { @@ -34,6 +34,7 @@ { "anycoin.me", true }, { "apadvantage.com", true }, { "api.intercom.io", false }, + { "api.lookout.com", false }, { "api.simple.com", false }, { "api.xero.com", false }, { "apis.google.com", true }, @@ -102,7 +103,7 @@ { "code.google.com", true }, { "codereview.appspot.com", false }, { "codereview.chromium.org", true }, - { "config.schokokeks.org", false }, + { "config.schokokeks.org", true }, { "conformal.com", true }, { "conrad-kostecki.de", true }, { "controlcenter.gigahost.dk", true }, @@ -134,9 +135,8 @@ { "docs.python.org", true }, { "domains.google.com", true }, { "donmez.ws", false }, - { "download.jitsi.org", false }, { "drive.google.com", true }, - { "dropbox.com", false }, + { "dropbox.com", true }, { "ebanking.indovinabank.com.vn", false }, { "ecosystem.atlassian.net", true }, { "edyou.eu", true }, @@ -193,7 +193,7 @@ { "haste.ch", true }, { "haufschild.de", true }, { "hausverbrauch.de", true }, - { "heha.co", true }, + { "heha.co", false }, { "helichat.de", true }, { "help.simpletax.ca", false }, { "helpium.de", true }, @@ -300,6 +300,7 @@ { "mylookout.com", false }, { "mynigma.org", true }, { "nachsenden.info", true }, + { "neg9.org", false }, { "neilwynne.com", false }, { "netzbit.de", true }, { "ng-security.com", true }, @@ -356,7 +357,6 @@ { "riesenmagnete.de", true }, { "rippleunion.com", true }, { "robteix.com", true }, - { "roddis.net", false }, { "romab.com", true }, { "rosenkeller.org", true }, { "roundcube.mayfirst.org", false }, @@ -365,7 +365,7 @@ { "sakaki.anime.my", true }, { "salaervergleich.com", true }, { "sandbox.mydigipass.com", false }, - { "schokokeks.org", false }, + { "schokokeks.org", true }, { "schwarzer.it", true }, { "scrambl.is", true }, { "script.google.com", true }, @@ -444,7 +444,6 @@ { "ukrainians.ch", true }, { "unterfrankenclan.de", true }, { "usaa.com", false }, - { "viennan.net", true }, { "vmoagents.com", false }, { "vocaloid.my", true }, { "w-spotlight.appspot.com", true }, @@ -457,7 +456,7 @@ { "webfilings.appspot.com", true }, { "webmail.gigahost.dk", false }, { "webmail.onlime.ch", false }, - { "webmail.schokokeks.org", false }, + { "webmail.schokokeks.org", true }, { "websenat.de", true }, { "welches-kinderfahrrad.de", true }, { "wepay.com", false }, @@ -476,7 +475,6 @@ { "writeapp.me", false }, { "wunderlist.com", true }, { "www.aclu.org", false }, - { "www.airbnb.com", true }, { "www.apollo-auto.com", true }, { "www.banking.co.at", false }, { "www.braintreepayments.com", false }, @@ -506,7 +504,8 @@ { "www.opsmate.com", true }, { "www.paypal.com", false }, { "www.python.org", true }, - { "www.schokokeks.org", false }, + { "www.roddis.net", true }, + { "www.schokokeks.org", true }, { "www.simbolo.co.uk", false }, { "www.simple.com", false }, { "www.therapynotes.com", false }, diff -Nru thunderbird-31.3.0+build1/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp thunderbird-31.4.0+build1/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp --- thunderbird-31.3.0+build1/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp 2014-11-28 19:14:19.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/security/manager/ssl/src/nsNSSIOLayer.cpp 2015-01-12 17:51:20.000000000 +0000 @@ -956,6 +956,17 @@ uint32_t reason; switch (err) { + case SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT: + // This is a clear signal that we've fallen back too many versions. Treat + // this as a hard failure now, but also mark the next higher version as + // being tolerant so that later attempts don't use this version (i.e., + // range.max), which makes the error unrecoverable without a full restart. + socketInfo->SharedState().IOLayerHelpers() + .rememberTolerantAtVersion(socketInfo->GetHostName(), + socketInfo->GetPort(), + range.max + 1); + return false; + case SSL_ERROR_BAD_MAC_ALERT: reason = 1; break; case SSL_ERROR_BAD_MAC_READ: reason = 2; break; case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: reason = 3; break; diff -Nru thunderbird-31.3.0+build1/mozilla/testing/config/mozharness/mac_config.py thunderbird-31.4.0+build1/mozilla/testing/config/mozharness/mac_config.py --- thunderbird-31.3.0+build1/mozilla/testing/config/mozharness/mac_config.py 2014-11-28 19:14:22.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/testing/config/mozharness/mac_config.py 2015-01-12 17:51:22.000000000 +0000 @@ -39,4 +39,5 @@ "mozbase_options": [ "-b", "%(binary_path)s" ], + "mac_res_subdir": "MacOS", } diff -Nru thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/linux32/releng.manifest thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/linux32/releng.manifest --- thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/linux32/releng.manifest 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/linux32/releng.manifest 2015-01-12 17:51:22.000000000 +0000 @@ -0,0 +1,7 @@ +[{ +"size": 1803072, +"digest": +"474cd191bd9331dc855d25186beae1dd64259ff5b5408fd2d4508d988034472528cbd2390c69a6ff1836437704cb101e769ad8da277bbb624da16ae4a5c75bdd", +"algorithm": "sha512", +"filename": "linux32-minidump_stackwalk" +}] diff -Nru thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/linux64/releng.manifest thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/linux64/releng.manifest --- thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/linux64/releng.manifest 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/linux64/releng.manifest 2015-01-12 17:51:22.000000000 +0000 @@ -0,0 +1,7 @@ +[{ +"size": 1926016, +"digest": +"2b7c8922f27244b5d244a2d4a6f7dcbe2b29227952fbde9396575805f83f34f62afd3e659614eb38210a817788dbef8042b049938e56779bcba0f72798272144", +"algorithm": "sha512", +"filename": "linux64-minidump_stackwalk" +}] diff -Nru thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/macosx64/releng.manifest thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/macosx64/releng.manifest --- thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/macosx64/releng.manifest 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/macosx64/releng.manifest 2015-01-12 17:51:22.000000000 +0000 @@ -0,0 +1,7 @@ +[{ +"size": 1316240, +"digest": +"3d94d249e390c687d9545c80b8ea7a6cff38538bc4104ad99103ee56b765fa1dedb30d95dcdfe9fad5665bdf9f0dfe246e1e544f37b03e952abee7ad38dc1caa", +"algorithm": "sha512", +"filename": "macosx64-minidump_stackwalk" +}] diff -Nru thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/win32/releng.manifest thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/win32/releng.manifest --- thunderbird-31.3.0+build1/mozilla/testing/config/tooltool-manifests/win32/releng.manifest 1970-01-01 00:00:00.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/testing/config/tooltool-manifests/win32/releng.manifest 2015-01-12 17:51:22.000000000 +0000 @@ -0,0 +1,7 @@ +[{ +"size": 5032443, +"digest": +"8228d0a47b4ec952759703503d74b456f592ec12c7be593b524c7065661bdb3d72c62d230536bce941e86aca2b74c389b24a26b21965510c4185a1e075a146b7", +"algorithm": "sha512", +"filename": "win32-minidump_stackwalk.exe" +}] diff -Nru thunderbird-31.3.0+build1/mozilla/xpcom/base/nsCycleCollector.cpp thunderbird-31.4.0+build1/mozilla/xpcom/base/nsCycleCollector.cpp --- thunderbird-31.3.0+build1/mozilla/xpcom/base/nsCycleCollector.cpp 2014-11-28 19:14:25.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/xpcom/base/nsCycleCollector.cpp 2015-01-12 17:51:26.000000000 +0000 @@ -916,7 +916,8 @@ { nsPurpleBufferEntry *eEnd = ArrayEnd(mEntries); for (nsPurpleBufferEntry *e = mEntries; e != eEnd; ++e) { - if (!(uintptr_t(e->mObject) & uintptr_t(1))) { + MOZ_ASSERT(e->mObject, "There should be no null mObject when we iterate over the purple buffer"); + if (!(uintptr_t(e->mObject) & uintptr_t(1)) && e->mObject) { aVisitor.Visit(aBuffer, e); } } diff -Nru thunderbird-31.3.0+build1/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp thunderbird-31.4.0+build1/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp --- thunderbird-31.3.0+build1/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp 2014-11-28 19:14:26.000000000 +0000 +++ thunderbird-31.4.0+build1/mozilla/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_arm.cpp 2015-01-12 17:51:26.000000000 +0000 @@ -224,6 +224,7 @@ *(uint64_t *)ireg_args = data; ireg_args += 2; } else { + ireg_args = end; if ((uint32_t)stack_args & 4) { stack_args++; }