From a34828f171d20e2505fdcb0d64d8975f95df7b01 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Fri, 20 Jun 2014 12:39:46 +0200 Subject: [PATCH] Bug 1027528 part 4 - Make JSON Quote function handle Latin1 strings. r=Waldo --- js/src/jit-test/tests/latin1/json.js | 11 +++++++++ js/src/json.cpp | 37 +++++++++++++++++++--------- js/src/json.h | 2 +- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/js/src/jit-test/tests/latin1/json.js b/js/src/jit-test/tests/latin1/json.js index 76d1643b1b7..7bcccc34e33 100644 --- a/js/src/jit-test/tests/latin1/json.js +++ b/js/src/jit-test/tests/latin1/json.js @@ -62,3 +62,14 @@ function testEvalHackNotJSON() { } } testEvalHackNotJSON(); + +function testQuote() { + // Latin1 + var s = toLatin1("abc--\x05-'\"-\n-\u00ff++"); + assertEq(JSON.stringify(s), '"abc--\\u0005-\'\\"-\\n-\xFF++"'); + + // TwoByte + s += "\uAAAA"; + assertEq(JSON.stringify(s), '"abc--\\u0005-\'\\"-\\n-\xFF++\uAAAA"'); +} +testQuote(); diff --git a/js/src/json.cpp b/js/src/json.cpp index 88e25aeacf3..d1155328bb5 100644 --- a/js/src/json.cpp +++ b/js/src/json.cpp @@ -7,6 +7,7 @@ #include "json.h" #include "mozilla/FloatingPoint.h" +#include "mozilla/Range.h" #include "jsarray.h" #include "jsatom.h" @@ -31,6 +32,8 @@ using namespace js::types; using mozilla::IsFinite; using mozilla::Maybe; +using mozilla::Range; +using mozilla::RangedPtr; const Class js::JSONClass = { js_JSON_str, @@ -55,20 +58,19 @@ static inline bool IsQuoteSpecialCharacter(jschar c) } /* ES5 15.12.3 Quote. */ +template static bool -Quote(JSContext *cx, StringBuffer &sb, JSString *str) +Quote(StringBuffer &sb, JSLinearString *str) { - JS::Anchor anchor(str); size_t len = str->length(); - const jschar *buf = str->getChars(cx); - if (!buf) - return false; /* Step 1. */ if (!sb.append('"')) return false; /* Step 2. */ + JS::AutoCheckCannotGC nogc; + const RangedPtr buf(str->chars(nogc), len); for (size_t i = 0; i < len; ++i) { /* Batch-append maximal character sequences containing no escapes. */ size_t mark = i; @@ -117,6 +119,19 @@ Quote(JSContext *cx, StringBuffer &sb, JSString *str) return sb.append('"'); } +static bool +Quote(JSContext *cx, StringBuffer &sb, JSString *str) +{ + JS::Anchor anchor(str); + JSLinearString *linear = str->ensureLinear(cx); + if (!linear) + return false; + + return linear->hasLatin1Chars() + ? Quote(sb, linear) + : Quote(sb, linear); +} + namespace { class StringifyContext @@ -774,8 +789,8 @@ Revive(JSContext *cx, HandleValue reviver, MutableHandleValue vp) template bool -js::ParseJSONWithReviver(JSContext *cx, mozilla::Range chars, - HandleValue reviver, MutableHandleValue vp) +js::ParseJSONWithReviver(JSContext *cx, const Range chars, HandleValue reviver, + MutableHandleValue vp) { /* 15.12.2 steps 2-3. */ JSONParser parser(cx, chars); @@ -789,12 +804,12 @@ js::ParseJSONWithReviver(JSContext *cx, mozilla::Range chars, } template bool -js::ParseJSONWithReviver(JSContext *cx, mozilla::Range chars, - HandleValue reviver, MutableHandleValue vp); +js::ParseJSONWithReviver(JSContext *cx, const Range chars, HandleValue reviver, + MutableHandleValue vp); template bool -js::ParseJSONWithReviver(JSContext *cx, mozilla::Range chars, - HandleValue reviver, MutableHandleValue vp); +js::ParseJSONWithReviver(JSContext *cx, const Range chars, HandleValue reviver, + MutableHandleValue vp); #if JS_HAS_TOSOURCE static bool diff --git a/js/src/json.h b/js/src/json.h index 043b30a6a85..40f86f3a75d 100644 --- a/js/src/json.h +++ b/js/src/json.h @@ -28,7 +28,7 @@ namespace js { template extern bool -ParseJSONWithReviver(JSContext *cx, mozilla::Range chars, +ParseJSONWithReviver(JSContext *cx, const mozilla::Range chars, HandleValue reviver, MutableHandleValue vp); } // namespace js