Bug 1504656 - Add patch to workaround ICU bug in RelativeDateTimeCacheData::getRelativeDateTimeUnitFormatter. r=jwalden, a=RyanVM
authorAndré Bargull <andre.bargull@gmail.com>
Sun, 02 Dec 2018 07:28:08 -0800
changeset 506437 d7fff5efe77d
parent 506436 d3c013ec52f1
child 506438 0c863fd33a72
push id10412
push userryanvm@gmail.com
push dateMon, 31 Dec 2018 01:51:41 +0000
treeherdermozilla-beta@d7fff5efe77d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden, RyanVM
bugs1504656
milestone65.0
Bug 1504656 - Add patch to workaround ICU bug in RelativeDateTimeCacheData::getRelativeDateTimeUnitFormatter. r=jwalden, a=RyanVM
intl/icu-patches/bug-1504656-relativetimeformat-plural-other-fallback.diff
intl/icu/source/i18n/reldatefmt.cpp
intl/update-icu.sh
js/src/tests/non262/Intl/RelativeTimeFormat/locale-fallback-handling.js
new file mode 100644
--- /dev/null
+++ b/intl/icu-patches/bug-1504656-relativetimeformat-plural-other-fallback.diff
@@ -0,0 +1,45 @@
+Workaround for https://unicode-org.atlassian.net/browse/ICU-20253
+
+https://bugzilla.mozilla.org/show_bug.cgi?id=1504656
+
+diff --git a/intl/icu/source/i18n/reldatefmt.cpp b/intl/icu/source/i18n/reldatefmt.cpp
+--- a/intl/icu/source/i18n/reldatefmt.cpp
++++ b/intl/icu/source/i18n/reldatefmt.cpp
+@@ -157,24 +157,30 @@ const UnicodeString& RelativeDateTimeCac
+  }
+ 
+  // Use fallback cache for SimpleFormatter relativeUnits.
+  const SimpleFormatter* RelativeDateTimeCacheData::getRelativeDateTimeUnitFormatter(
+         int32_t fStyle,
+         URelativeDateTimeUnit unit,
+         int32_t pastFutureIndex,
+         int32_t pluralUnit) const {
+-    int32_t style = fStyle;
+-    do {
+-        if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != nullptr) {
+-            return relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit];
++    while (true) {
++        int32_t style = fStyle;
++        do {
++            if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != nullptr) {
++                return relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit];
++            }
++            style = fallBackCache[style];
++        } while (style != -1);
++
++        if (pluralUnit == StandardPlural::OTHER) {
++            return nullptr;  // No formatter found.
+         }
+-        style = fallBackCache[style];
+-    } while (style != -1);
+-    return nullptr;  // No formatter found.
++        pluralUnit = StandardPlural::OTHER;
++    }
+  }
+ 
+ static UBool getStringWithFallback(
+         const UResourceBundle *resource,
+         const char *key,
+         UnicodeString &result,
+         UErrorCode &status) {
+     int32_t len = 0;
--- a/intl/icu/source/i18n/reldatefmt.cpp
+++ b/intl/icu/source/i18n/reldatefmt.cpp
@@ -157,24 +157,30 @@ const UnicodeString& RelativeDateTimeCac
  }
 
  // Use fallback cache for SimpleFormatter relativeUnits.
  const SimpleFormatter* RelativeDateTimeCacheData::getRelativeDateTimeUnitFormatter(
         int32_t fStyle,
         URelativeDateTimeUnit unit,
         int32_t pastFutureIndex,
         int32_t pluralUnit) const {
-    int32_t style = fStyle;
-    do {
-        if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != nullptr) {
-            return relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit];
+    while (true) {
+        int32_t style = fStyle;
+        do {
+            if (relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit] != nullptr) {
+                return relativeUnitsFormatters[style][unit][pastFutureIndex][pluralUnit];
+            }
+            style = fallBackCache[style];
+        } while (style != -1);
+
+        if (pluralUnit == StandardPlural::OTHER) {
+            return nullptr;  // No formatter found.
         }
-        style = fallBackCache[style];
-    } while (style != -1);
-    return nullptr;  // No formatter found.
+        pluralUnit = StandardPlural::OTHER;
+    }
  }
 
 static UBool getStringWithFallback(
         const UResourceBundle *resource,
         const char *key,
         UnicodeString &result,
         UErrorCode &status) {
     int32_t len = 0;
--- a/intl/update-icu.sh
+++ b/intl/update-icu.sh
@@ -81,16 +81,17 @@ find ${icu_dir}/source/data/zone \
     -name tzdbNames.txt -prune -or \
     -name '*.txt' -print | xargs sed -i '/^\s*zoneStrings{/{N; s/^\s*zoneStrings{\n\s*}// }; /^$/d'
 
 for patch in \
  bug-915735 \
  suppress-warnings.diff \
  bug-1172609-timezone-recreateDefault.diff \
  bug-1198952-workaround-make-3.82-bug.diff \
+ bug-1504656-relativetimeformat-plural-other-fallback.diff \
 ; do
   echo "Applying local patch $patch"
   patch -d ${icu_dir}/../../ -p1 --no-backup-if-mismatch < ${icu_dir}/../icu-patches/$patch
 done
 
 topsrcdir=`dirname $0`/../
 python ${topsrcdir}/js/src/tests/non262/String/make-normalize-generateddata-input.py $topsrcdir
 
new file mode 100644
--- /dev/null
+++ b/js/src/tests/non262/Intl/RelativeTimeFormat/locale-fallback-handling.js
@@ -0,0 +1,15 @@
+// |reftest| skip-if(!this.hasOwnProperty("Intl"))
+/* 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/. */
+
+// In locales that don't have a relative-date/time formatter -- and presently
+// "ak" is such a locale -- behavior is expected to fall back to the root-locale
+// formatter.  This test verifies such fallback works as long as "ak" satisfies
+// these properties; "ak" may safely be changed to a different locale if that
+// ever changes.  See bug 1504656.
+assertEq(new Intl.RelativeTimeFormat("ak").format(1, "second"),
+         "+1 s");
+
+if (typeof reportCompare === "function")
+  reportCompare(0, 0, 'ok');