From a9a7517ec17faa284f202638e5717f0b72d38332 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Fri, 20 Jun 2014 12:39:44 +0200 Subject: [PATCH] Bug 1027528 part 3 - Make JS_EncodeString and friends handle Latin1 strings. r=Waldo --- js/public/CharacterEncoding.h | 3 ++- js/src/frontend/TokenStream.cpp | 5 +++-- js/src/jsapi-tests/testUTF8.cpp | 4 +++- js/src/jsapi.cpp | 33 +++++++++++++++++++++++---------- js/src/jscntxt.cpp | 8 ++++---- js/src/jsopcode.cpp | 12 +++--------- js/src/jsreflect.cpp | 8 +------- js/src/vm/CharacterEncoding.cpp | 12 ++++++++---- 8 files changed, 47 insertions(+), 38 deletions(-) diff --git a/js/public/CharacterEncoding.h b/js/public/CharacterEncoding.h index c147ceb94ed8..9fee2208cda1 100644 --- a/js/public/CharacterEncoding.h +++ b/js/public/CharacterEncoding.h @@ -175,7 +175,8 @@ class ConstTwoByteChars : public mozilla::RangedPtr * This method cannot trigger GC. */ extern Latin1CharsZ -LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars); +LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, + const mozilla::Range tbchars); template extern UTF8CharsZ diff --git a/js/src/frontend/TokenStream.cpp b/js/src/frontend/TokenStream.cpp index 61d8763f0ff7..07b39de050d1 100644 --- a/js/src/frontend/TokenStream.cpp +++ b/js/src/frontend/TokenStream.cpp @@ -710,8 +710,9 @@ TokenStream::reportCompileErrorNumberVA(uint32_t offset, unsigned flags, unsigne err.report.uclinebuf = windowBuf.stealChars(); if (!err.report.uclinebuf) return false; - TwoByteChars tbchars(err.report.uclinebuf, windowLength); - err.report.linebuf = LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str(); + + mozilla::Range tbchars(err.report.uclinebuf, windowLength); + err.report.linebuf = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str(); if (!err.report.linebuf) return false; diff --git a/js/src/jsapi-tests/testUTF8.cpp b/js/src/jsapi-tests/testUTF8.cpp index cea6055135d3..400508af5fbe 100644 --- a/js/src/jsapi-tests/testUTF8.cpp +++ b/js/src/jsapi-tests/testUTF8.cpp @@ -5,6 +5,8 @@ * 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/Range.h" + #include "jsapi.h" #include "jsstr.h" @@ -38,7 +40,7 @@ END_TEST(testUTF8_bigUTF8) BEGIN_TEST(testUTF8_badSurrogate) { static const jschar badSurrogate[] = { 'A', 'B', 'C', 0xDEEE, 'D', 'E', 0 }; - JS::TwoByteChars tbchars(badSurrogate, js_strlen(badSurrogate)); + mozilla::Range tbchars(badSurrogate, js_strlen(badSurrogate)); JS::Latin1CharsZ latin1 = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars); CHECK(latin1); CHECK(latin1[3] == 0x00EE); diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 793db425d8dc..028a8de1a194 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -5502,17 +5502,34 @@ JS_DecodeBytes(JSContext *cx, const char *src, size_t srclen, jschar *dst, size_ return true; } +static char * +EncodeLatin1(ExclusiveContext *cx, JSString *str) +{ + JSLinearString *linear = str->ensureLinear(cx); + if (!linear) + return nullptr; + + JS::AutoCheckCannotGC nogc; + if (linear->hasTwoByteChars()) + return JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->twoByteRange(nogc)).c_str(); + + size_t len = str->length(); + Latin1Char *buf = cx->pod_malloc(len + 1); + if (!buf) + return nullptr; + + mozilla::PodCopy(buf, linear->latin1Chars(nogc), len); + buf[len] = '\0'; + return reinterpret_cast(buf); +} + JS_PUBLIC_API(char *) JS_EncodeString(JSContext *cx, JSString *str) { AssertHeapIsIdle(cx); CHECK_REQUEST(cx); - JSLinearString *linear = str->ensureLinear(cx); - if (!linear) - return nullptr; - - return LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str(); + return EncodeLatin1(cx, str); } JS_PUBLIC_API(char *) @@ -6477,11 +6494,7 @@ JS::SetAsmJSCacheOps(JSRuntime *rt, const JS::AsmJSCacheOps *ops) char * JSAutoByteString::encodeLatin1(ExclusiveContext *cx, JSString *str) { - JSLinearString *linear = str->ensureLinear(cx); - if (!linear) - return nullptr; - - mBytes = LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str(); + mBytes = EncodeLatin1(cx, str); return mBytes; } diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 30b1c00a442f..a90255e0eacd 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -758,10 +758,10 @@ js_ExpandErrorArguments(ExclusiveContext *cx, JSErrorCallback callback, JS_ASSERT(expandedArgs == argCount); *out = 0; js_free(buffer); - TwoByteChars ucmsg(reportp->ucmessage, - PointerRangeSize(static_cast(reportp->ucmessage), - static_cast(out))); - *messagep = LossyTwoByteCharsToNewLatin1CharsZ(cx, ucmsg).c_str(); + size_t msgLen = PointerRangeSize(static_cast(reportp->ucmessage), + static_cast(out)); + mozilla::Range ucmsg(reportp->ucmessage, msgLen); + *messagep = JS::LossyTwoByteCharsToNewLatin1CharsZ(cx, ucmsg).c_str(); if (!*messagep) goto error; } diff --git a/js/src/jsopcode.cpp b/js/src/jsopcode.cpp index 9dd1595e70fb..0119e22648b0 100644 --- a/js/src/jsopcode.cpp +++ b/js/src/jsopcode.cpp @@ -1807,11 +1807,7 @@ js::DecompileValueGenerator(JSContext *cx, int spindex, HandleValue v, return nullptr; } - RootedLinearString linear(cx, fallback->ensureLinear(cx)); - if (!linear) - return nullptr; - TwoByteChars tbchars(linear->chars(), linear->length()); - return LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str(); + return JS_EncodeString(cx, fallback); } static bool @@ -1890,14 +1886,12 @@ js::DecompileArgument(JSContext *cx, int formalIndex, HandleValue v) } if (v.isUndefined()) return JS_strdup(cx, js_undefined_str); // Prevent users from seeing "(void 0)" + RootedString fallback(cx, ValueToSource(cx, v)); if (!fallback) return nullptr; - RootedLinearString linear(cx, fallback->ensureLinear(cx)); - if (!linear) - return nullptr; - return LossyTwoByteCharsToNewLatin1CharsZ(cx, linear->range()).c_str(); + return JS_EncodeString(cx, fallback); } bool diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index 05cf7eaf180c..5c44bf4fb6b9 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -3254,13 +3254,7 @@ reflect_parse(JSContext *cx, uint32_t argc, jsval *vp) if (!str) return false; - size_t length = str->length(); - const jschar *chars = str->getChars(cx); - if (!chars) - return false; - - TwoByteChars tbchars(chars, length); - filename = LossyTwoByteCharsToNewLatin1CharsZ(cx, tbchars).c_str(); + filename = JS_EncodeString(cx, str); if (!filename) return false; } diff --git a/js/src/vm/CharacterEncoding.cpp b/js/src/vm/CharacterEncoding.cpp index e68beb384ad2..cdb1f2f99e82 100644 --- a/js/src/vm/CharacterEncoding.cpp +++ b/js/src/vm/CharacterEncoding.cpp @@ -6,13 +6,17 @@ #include "js/CharacterEncoding.h" +#include "mozilla/Range.h" + #include "jscntxt.h" #include "jsprf.h" using namespace JS; +using mozilla::Range; + Latin1CharsZ -JS::LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, TwoByteChars tbchars) +JS::LossyTwoByteCharsToNewLatin1CharsZ(js::ThreadSafeContext *cx, const Range tbchars) { JS_ASSERT(cx); size_t len = tbchars.length(); @@ -140,7 +144,7 @@ bufferTooSmall: template UTF8CharsZ -JS::CharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, const mozilla::Range chars) +JS::CharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, const Range chars) { JS_ASSERT(cx); @@ -161,10 +165,10 @@ JS::CharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, const mozilla::Range chars); +JS::CharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, const Range chars); template UTF8CharsZ -JS::CharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, mozilla::Range chars); +JS::CharsToNewUTF8CharsZ(js::ThreadSafeContext *cx, const Range chars); static const uint32_t INVALID_UTF8 = UINT32_MAX;