From f5787fc732402e7e3af38e0d7a9ef609d2be59f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Bargull?= Date: Wed, 5 Sep 2018 01:25:12 -0700 Subject: [PATCH] Bug 1485066 - Part 12: Change the decompiler to return UTF-8 encoded strings. r=Waldo --- js/public/CharacterEncoding.h | 2 +- js/src/builtin/Object.cpp | 4 +-- js/src/builtin/Stream.cpp | 4 +-- js/src/perf/jsperf.cpp | 2 +- js/src/shell/js.cpp | 3 +- js/src/vm/BytecodeUtil.cpp | 15 ++++++---- js/src/vm/ForOfIterator.cpp | 2 +- js/src/vm/JSContext.cpp | 51 +++++++++++++--------------------- js/src/vm/JSObject.cpp | 8 +++--- js/src/vm/Printer.cpp | 21 ++++++-------- js/src/vm/SelfHosting.cpp | 6 ++-- js/src/vm/TypedArrayObject.cpp | 4 +-- 12 files changed, 54 insertions(+), 68 deletions(-) diff --git a/js/public/CharacterEncoding.h b/js/public/CharacterEncoding.h index 6c1daefecb5c..a1e006fc6228 100644 --- a/js/public/CharacterEncoding.h +++ b/js/public/CharacterEncoding.h @@ -117,7 +117,7 @@ class UTF8CharsZ : public mozilla::RangedPtr * A wrapper for a "const char*" that is encoded using UTF-8. * This class does not manage ownership of the data; that is left * to others. This differs from UTF8CharsZ in that the chars are - * const and it allows assignment. + * const and it disallows assignment. */ class JS_PUBLIC_API(ConstUTF8CharsZ) { diff --git a/js/src/builtin/Object.cpp b/js/src/builtin/Object.cpp index 8ea50d47c605..ca9db99c1a19 100644 --- a/js/src/builtin/Object.cpp +++ b/js/src/builtin/Object.cpp @@ -1057,8 +1057,8 @@ js::obj_create(JSContext* cx, unsigned argc, Value* vp) if (!bytes) return false; - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, - bytes.get(), "not an object or null"); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, + bytes.get(), "not an object or null"); return false; } diff --git a/js/src/builtin/Stream.cpp b/js/src/builtin/Stream.cpp index 5ccbce7b48f0..3cc1ed98d750 100644 --- a/js/src/builtin/Stream.cpp +++ b/js/src/builtin/Stream.cpp @@ -277,8 +277,8 @@ ReportArgTypeError(JSContext* cx, const char* funName, const char* expectedType, if (!bytes) return; - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE, funName, - expectedType, bytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE, funName, + expectedType, bytes.get()); } static MOZ_MUST_USE bool diff --git a/js/src/perf/jsperf.cpp b/js/src/perf/jsperf.cpp index f177e0d3c9fd..8561105a13d2 100644 --- a/js/src/perf/jsperf.cpp +++ b/js/src/perf/jsperf.cpp @@ -223,7 +223,7 @@ GetPM(JSContext* cx, JS::HandleValue value, const char* fname) UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, value, nullptr); if (!bytes) return nullptr; - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, 0, JSMSG_NOT_NONNULL_OBJECT, bytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, 0, JSMSG_NOT_NONNULL_OBJECT, bytes.get()); return nullptr; } RootedObject obj(cx, &value.toObject()); diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index a125fb515847..b86cced48459 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -3100,7 +3100,8 @@ DisassembleToString(JSContext* cx, unsigned argc, Value* vp) if (!DisassembleToSprinter(cx, args.length(), vp, &sprinter)) return false; - JSString* str = JS_NewStringCopyZ(cx, sprinter.string()); + JS::ConstUTF8CharsZ utf8chars(sprinter.string(), strlen(sprinter.string())); + JSString* str = JS_NewStringCopyUTF8Z(cx, utf8chars); if (!str) return false; args.rval().setString(str); diff --git a/js/src/vm/BytecodeUtil.cpp b/js/src/vm/BytecodeUtil.cpp index e11ae81e7ec9..951920056e0d 100644 --- a/js/src/vm/BytecodeUtil.cpp +++ b/js/src/vm/BytecodeUtil.cpp @@ -1147,14 +1147,14 @@ ToDisassemblySource(JSContext* cx, HandleValue v) JSString* str = JS_DecompileFunction(cx, fun); if (!str) return nullptr; - return EncodeLatin1(cx, str); + return StringToNewUTF8CharsZ(cx, *str); } if (obj.is()) { JSString* source = obj.as().toString(cx); if (!source) return nullptr; - return EncodeLatin1(cx, source); + return StringToNewUTF8CharsZ(cx, *source); } } @@ -2299,7 +2299,7 @@ js::DecompileValueGenerator(JSContext* cx, int spindex, HandleValue v, return nullptr; } - return EncodeLatin1(cx, fallback); + return StringToNewUTF8CharsZ(cx, *fallback); } static bool @@ -2379,8 +2379,10 @@ js::DecompileArgument(JSContext* cx, int formalIndex, HandleValue v) UniqueChars result; if (!DecompileArgumentFromStack(cx, formalIndex, &result)) return nullptr; - if (result && strcmp(result.get(), "(intermediate value)")) - return NewStringCopyZ(cx, result.get()); + if (result && strcmp(result.get(), "(intermediate value)")) { + JS::ConstUTF8CharsZ utf8chars(result.get(), strlen(result.get())); + return NewStringCopyUTF8Z(cx, utf8chars); + } } if (v.isUndefined()) return cx->names().undefined; // Prevent users from seeing "(void 0)" @@ -2692,7 +2694,8 @@ GetPCCountJSON(JSContext* cx, const ScriptAndCounts& sac, StringBuffer& buf) UniqueChars text = ed.getOutput(); if (!text) return false; - JSString* str = NewLatin1StringZ(cx, std::move(text)); + JS::ConstUTF8CharsZ utf8chars(text.get(), strlen(text.get())); + JSString* str = NewStringCopyUTF8Z(cx, utf8chars); if (!AppendJSONProperty(buf, "text")) return false; if (!str || !(str = StringToSource(cx, str))) diff --git a/js/src/vm/ForOfIterator.cpp b/js/src/vm/ForOfIterator.cpp index 6f1f66e922ba..0ce86322fdf3 100644 --- a/js/src/vm/ForOfIterator.cpp +++ b/js/src/vm/ForOfIterator.cpp @@ -67,7 +67,7 @@ ForOfIterator::init(HandleValue iterable, NonIterableBehavior nonIterableBehavio UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, iterable, nullptr); if (!bytes) return false; - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_ITERABLE, bytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_ITERABLE, bytes.get()); return false; } diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp index 4d8a2232ad32..966ab41bc73f 100644 --- a/js/src/vm/JSContext.cpp +++ b/js/src/vm/JSContext.cpp @@ -919,43 +919,31 @@ js::ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx, HandleValue v, bool return; if (strcmp(bytes.get(), js_undefined_str) == 0 || strcmp(bytes.get(), js_null_str) == 0) { - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NO_PROPERTIES, - bytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NO_PROPERTIES, bytes.get()); } else if (v.isUndefined()) { - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, - bytes.get(), js_undefined_str); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, bytes.get(), + js_undefined_str); } else { MOZ_ASSERT(v.isNull()); - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, - bytes.get(), js_null_str); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, bytes.get(), + js_null_str); } } -static UniqueChars -EncodeIdAsLatin1(JSContext* cx, HandleId id) -{ - RootedValue idVal(cx, IdToValue(id)); - JSString* idStr = ValueToSource(cx, idVal); - if (!idStr) - return nullptr; - - return EncodeLatin1(cx, idStr); -} - void js::ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx, HandleValue v, HandleId key, bool reportScanStack) { MOZ_ASSERT(v.isNullOrUndefined()); - UniqueChars keyBytes = EncodeIdAsLatin1(cx, key); + UniqueChars keyBytes = IdToPrintableUTF8(cx, key, IdToPrintableBehavior::IdIsPropertyKey); if (!keyBytes) return; if (!reportScanStack) { - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL, - keyBytes.get(), - v.isUndefined() ? js_undefined_str : js_null_str); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL, + keyBytes.get(), + v.isUndefined() ? js_undefined_str : js_null_str); return; } @@ -964,15 +952,15 @@ js::ReportIsNullOrUndefinedForPropertyAccess(JSContext* cx, HandleValue v, Handl return; if (strcmp(bytes.get(), js_undefined_str) == 0 || strcmp(bytes.get(), js_null_str) == 0) { - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL, - keyBytes.get(), bytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL, + keyBytes.get(), bytes.get()); } else if (v.isUndefined()) { - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL_EXPR, - bytes.get(), js_undefined_str, keyBytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL_EXPR, + bytes.get(), js_undefined_str, keyBytes.get()); } else { MOZ_ASSERT(v.isNull()); - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL_EXPR, - bytes.get(), js_null_str, keyBytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_PROPERTY_FAIL_EXPR, + bytes.get(), js_null_str, keyBytes.get()); } } @@ -989,9 +977,8 @@ js::ReportMissingArg(JSContext* cx, HandleValue v, unsigned arg) if (!bytes) return; } - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, - JSMSG_MISSING_FUN_ARG, - argbuf, bytes ? bytes.get() : ""); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_MISSING_FUN_ARG, + argbuf, bytes ? bytes.get() : ""); } bool @@ -1005,8 +992,8 @@ js::ReportValueErrorFlags(JSContext* cx, unsigned flags, const unsigned errorNum if (!bytes) return false; - return JS_ReportErrorFlagsAndNumberLatin1(cx, flags, GetErrorMessage, nullptr, errorNumber, - bytes.get(), arg1, arg2); + return JS_ReportErrorFlagsAndNumberUTF8(cx, flags, GetErrorMessage, nullptr, errorNumber, + bytes.get(), arg1, arg2); } JSObject* diff --git a/js/src/vm/JSObject.cpp b/js/src/vm/JSObject.cpp index ad2d7ae8c3a8..dd19fc95b7e5 100644 --- a/js/src/vm/JSObject.cpp +++ b/js/src/vm/JSObject.cpp @@ -84,8 +84,8 @@ js::ReportNotObject(JSContext* cx, HandleValue v) MOZ_ASSERT(!v.isObject()); if (UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, nullptr)) { - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, - bytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_NONNULL_OBJECT, + bytes.get()); } } @@ -228,8 +228,8 @@ js::GetFirstArgumentAsObject(JSContext* cx, const CallArgs& args, const char* me UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, v, nullptr); if (!bytes) return false; - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, - bytes.get(), "not an object"); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE, + bytes.get(), "not an object"); return false; } diff --git a/js/src/vm/Printer.cpp b/js/src/vm/Printer.cpp index e3d63005dfe3..b83c1a48a69a 100644 --- a/js/src/vm/Printer.cpp +++ b/js/src/vm/Printer.cpp @@ -8,6 +8,7 @@ #include "mozilla/PodOperations.h" #include "mozilla/Printf.h" +#include "mozilla/RangedPtr.h" #include #include @@ -16,6 +17,7 @@ #include "jsutil.h" #include "ds/LifoAlloc.h" +#include "js/CharacterEncoding.h" #include "util/Text.h" #include "util/Windows.h" #include "vm/JSContext.h" @@ -223,24 +225,17 @@ Sprinter::putString(JSString* s) { InvariantChecker ic(this); - size_t length = s->length(); + JSFlatString* flat = s->ensureFlat(context); + if (!flat) + return false; + + size_t length = JS::GetDeflatedUTF8StringLength(flat); char* buffer = reserve(length); if (!buffer) return false; - JSLinearString* linear = s->ensureLinear(context); - if (!linear) - return false; - - JS::AutoCheckCannotGC nogc; - if (linear->hasLatin1Chars()) { - PodCopy(reinterpret_cast(buffer), linear->latin1Chars(nogc), length); - } else { - const char16_t* src = linear->twoByteChars(nogc); - for (size_t i = 0; i < length; i++) - buffer[i] = char(src[i]); - } + JS::DeflateStringToUTF8Buffer(flat, mozilla::RangedPtr(buffer, length)); buffer[length] = '\0'; return true; diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index 54a8fde2f9fe..0cbaa94e877b 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -299,7 +299,7 @@ ThrowErrorWithType(JSContext* cx, JSExnType type, const CallArgs& args) JSString* str = ToString(cx, val); if (!str) return; - errorArgs[i - 1] = EncodeLatin1(cx, str); + errorArgs[i - 1] = StringToNewUTF8CharsZ(cx, *str); } else { errorArgs[i - 1] = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, val, nullptr); } @@ -307,8 +307,8 @@ ThrowErrorWithType(JSContext* cx, JSExnType type, const CallArgs& args) return; } - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, errorNumber, - errorArgs[0].get(), errorArgs[1].get(), errorArgs[2].get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, errorNumber, + errorArgs[0].get(), errorArgs[1].get(), errorArgs[2].get()); } static bool diff --git a/js/src/vm/TypedArrayObject.cpp b/js/src/vm/TypedArrayObject.cpp index 88de91b78b46..246773331186 100644 --- a/js/src/vm/TypedArrayObject.cpp +++ b/js/src/vm/TypedArrayObject.cpp @@ -1324,8 +1324,8 @@ TypedArrayObjectTemplate::fromObject(JSContext* cx, HandleObject other, Handl UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, otherVal, nullptr); if (!bytes) return nullptr; - JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_ITERABLE, - bytes.get()); + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_NOT_ITERABLE, + bytes.get()); return nullptr; }