Use simpler method of conversion and always get a null-terminated string draft
authorDaniel Ehrenberg <littledan@igalia.com>
Tue, 28 Feb 2017 11:39:14 +0100
changeset 490391 a0aa14e5439de6b6acaf7d5d9ff0641730b8d231
parent 489656 bf0522bd932d52427fa429cccc17d4860bf1c312
child 547248 5e9ce0287ec2b1458040a061f0aafe5c0fc8d685
push id47086
push userbmo:littledan@chromium.org
push dateTue, 28 Feb 2017 10:40:37 +0000
milestone54.0a1
Use simpler method of conversion and always get a null-terminated string MozReview-Commit-ID: ARaPZRid5EM
js/src/builtin/Intl.cpp
--- a/js/src/builtin/Intl.cpp
+++ b/js/src/builtin/Intl.cpp
@@ -1370,26 +1370,29 @@ js::intl_CompareStrings(JSContext* cx, u
 
 bool
 js::intl_CurrencyDigits(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     MOZ_ASSERT(args.length() == 1);
     MOZ_ASSERT(args[0].isString());
 
-    RootedString str(cx, args[0].toString());
-    AutoStableStringChars stableChars(cx);
-    if (!stableChars.initTwoByte(cx, str))
-        return false;
-    mozilla::Range<const char16_t> chars = stableChars.twoByteRange();
-    // This might not be null-terminated, but ICU only ever looks
-    // at the first three UChars, since an ISO currency code always has a
-    // length of three
+    UChar chars[4];
+    {
+        JSLinearString* currency = args[0].toString()->ensureLinear(cx);
+        if (!currency)
+            return false;
+
+        MOZ_ASSERT(currency->length() == 3);
+        for (size_t i = 0; i < 3; i++)
+            chars[i] = currency->latin1OrTwoByteChar(i);
+        chars[3] = '\0';
+    }
     UErrorCode status = U_ZERO_ERROR;
-    int32_t digits = ucurr_getDefaultFractionDigits(Char16ToUChar(chars.begin().get()), &status);
+    int32_t digits = ucurr_getDefaultFractionDigits(chars, &status);
     if (U_FAILURE(status)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
         return false;
     }
     args.rval().setInt32(digits);
     return true;
 }