WebKit Bugzilla
Attachment 357828 Details for
Bug 191677
: [JSC] Implement "well-formed JSON.stringify" proposal
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-191677-20181221030913.patch (text/plain), 11.75 KB, created by
Yusuke Suzuki
on 2018-12-20 10:09:14 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2018-12-20 10:09:14 PST
Size:
11.75 KB
patch
obsolete
>Subversion Revision: 239441 >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index 0dfcf22d53d5cfaeefa5558983384da377dd16a8..764853a7bcc0195cdd03b92b06f72da8b0509c5e 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,19 @@ >+2018-12-20 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ [JSC] Implement "well-formed JSON.stringify" proposal >+ https://bugs.webkit.org/show_bug.cgi?id=191677 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch implements "well-formed JSON.stringify" proposal[1], which is now stage 3. >+ JSON.stringify appended surrogate pair codes even if it is not paired appropriately. >+ The proposal requires that broken surrogate pairs are unicode-escaped. >+ >+ [1]: https://github.com/tc39/proposal-well-formed-stringify >+ >+ * wtf/text/StringBuilderJSON.cpp: >+ (WTF::appendQuotedJSONStringInternal): >+ > 2018-12-20 Tadeu Zagallo <tzagallo@apple.com> > > Consistently use MaxLength for all WTF strings >diff --git a/Source/WTF/wtf/text/StringBuilderJSON.cpp b/Source/WTF/wtf/text/StringBuilderJSON.cpp >index f382c1bf14bfee09c203cf86ebc1fd0bb79d517f..c3118b6391bfef2b8cef87d66af3bd6b9b71b90b 100644 >--- a/Source/WTF/wtf/text/StringBuilderJSON.cpp >+++ b/Source/WTF/wtf/text/StringBuilderJSON.cpp >@@ -57,20 +57,47 @@ ALWAYS_INLINE static void appendQuotedJSONStringInternal(OutputCharacterType*& o > { > for (auto* end = input + length; input != end; ++input) { > auto character = *input; >- auto escaped = escapedFormsForJSON[character & 0xFF]; >- if (LIKELY(!escaped || character > 0xFF)) { >+ if (LIKELY(character <= 0xFF)) { >+ auto escaped = escapedFormsForJSON[character]; >+ if (LIKELY(!escaped)) { >+ *output++ = character; >+ continue; >+ } >+ >+ *output++ = '\\'; >+ *output++ = escaped; >+ if (UNLIKELY(escaped == 'u')) { >+ *output++ = '0'; >+ *output++ = '0'; >+ *output++ = upperNibbleToLowercaseASCIIHexDigit(character); >+ *output++ = lowerNibbleToLowercaseASCIIHexDigit(character); >+ } >+ continue; >+ } >+ >+ if (LIKELY(!U16_IS_SURROGATE(character))) { > *output++ = character; > continue; > } > >- *output++ = '\\'; >- *output++ = escaped; >- if (UNLIKELY(escaped == 'u')) { >- *output++ = '0'; >- *output++ = '0'; >- *output++ = upperNibbleToLowercaseASCIIHexDigit(character); >- *output++ = lowerNibbleToLowercaseASCIIHexDigit(character); >+ auto next = input + 1; >+ bool isValidSurrogatePair = U16_IS_SURROGATE_LEAD(character) && next != end && U16_IS_TRAIL(*next); >+ if (isValidSurrogatePair) { >+ *output++ = character; >+ *output++ = *next; >+ ++input; >+ continue; > } >+ >+ uint8_t upper = static_cast<uint32_t>(character) >> 8; >+ uint8_t lower = static_cast<uint8_t>(character); >+ *output++ = '\\'; >+ *output++ = 'u'; >+ *output++ = upperNibbleToLowercaseASCIIHexDigit(upper); >+ *output++ = lowerNibbleToLowercaseASCIIHexDigit(upper); >+ *output++ = upperNibbleToLowercaseASCIIHexDigit(lower); >+ *output++ = lowerNibbleToLowercaseASCIIHexDigit(lower); >+ continue; > } > } > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 222032a577ce269f99b003d01585775e5c273c85..f90cd77da514ec4839e9592456cd8fa8a94f1836 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,18 @@ >+2018-12-20 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ [JSC] Implement "well-formed JSON.stringify" proposal >+ https://bugs.webkit.org/show_bug.cgi?id=191677 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * css3/escape-dom-api-expected.txt: >+ * js/dom/webidl-type-mapping-expected.txt: >+ * js/resources/json2-es5-compat.js: >+ (isHighSurrogate): >+ (isLowSurrogate): >+ (isSurrogate): >+ (quote): >+ > 2018-12-20 Wenson Hsieh <wenson_hsieh@apple.com> > > [iOS] Focusing an editable element should scroll to reveal the selection >diff --git a/LayoutTests/css3/escape-dom-api-expected.txt b/LayoutTests/css3/escape-dom-api-expected.txt >index cef65ce289203cb79fbe20546cf8f3287e3772ab..c851c96ef745e0118673126ad8982a3104b8d2c1 100644 >--- a/LayoutTests/css3/escape-dom-api-expected.txt >+++ b/LayoutTests/css3/escape-dom-api-expected.txt >@@ -61,8 +61,8 @@ PASS CSS.escape('abcdefghijklmnopqrstuvwxyz') is "abcdefghijklmnopqrstuvwxyz" > PASS CSS.escape('ABCDEFGHIJKLMNOPQRSTUVWXYZ') is "ABCDEFGHIJKLMNOPQRSTUVWXYZ" > PASS CSS.escape(' !xy') is "\\ \\!xy" > PASS CSS.escape('ðÂÂÂ') is "ðÂÂÂ" >-PASS CSS.escape('üÂ') is "üÂ" >-PASS CSS.escape('à´') is "à´" >+PASS CSS.escape('üÂ') is "\udf06" >+PASS CSS.escape('à´') is "\ud834" > PASS successfullyParsed is true > > TEST COMPLETE >diff --git a/LayoutTests/js/dom/webidl-type-mapping-expected.txt b/LayoutTests/js/dom/webidl-type-mapping-expected.txt >index 1e0fe3a825e80a053ec4d1c54ea96d2c041331fb..75a4da60b81ecfbbc72f6cd504deb9e2a15321c6 100644 >--- a/LayoutTests/js/dom/webidl-type-mapping-expected.txt >+++ b/LayoutTests/js/dom/webidl-type-mapping-expected.txt >@@ -1019,26 +1019,26 @@ PASS converter.testUSVString = {toString: function() { throw Error(); }} threw e > PASS converter.testString = {toString: function() { throw Error(); }} threw exception Error. > PASS converter.testUSVString is "ÃÂ" > PASS converter.testString is "ÃÂ" >-converter.testUSVString = "àÂ" >-converter.testString = "àÂ" >+converter.testUSVString = "\ud800" >+converter.testString = "\ud800" > PASS converter.testUSVString is "�" >-PASS converter.testString is "àÂ" >-converter.testUSVString = "ðÂ" >-converter.testString = "ðÂ" >+PASS converter.testString is "\ud800" >+converter.testUSVString = "\udc00" >+converter.testString = "\udc00" > PASS converter.testUSVString is "�" >-PASS converter.testString is "ðÂ" >-converter.testUSVString = "àÂ\u0000" >-converter.testString = "àÂ\u0000" >+PASS converter.testString is "\udc00" >+converter.testUSVString = "\ud800\u0000" >+converter.testString = "\ud800\u0000" > PASS converter.testUSVString is "�\u0000" >-PASS converter.testString is "àÂ\u0000" >-converter.testUSVString = "ðÂ\u0000" >-converter.testString = "ðÂ\u0000" >+PASS converter.testString is "\ud800\u0000" >+converter.testUSVString = "\udc00\u0000" >+converter.testString = "\udc00\u0000" > PASS converter.testUSVString is "�\u0000" >-PASS converter.testString is "ðÂ\u0000" >-converter.testUSVString = "ðÂàÂ" >-converter.testString = "ðÂàÂ" >+PASS converter.testString is "\udc00\u0000" >+converter.testUSVString = "\udc00\ud800" >+converter.testString = "\udc00\ud800" > PASS converter.testUSVString is "��" >-PASS converter.testString is "ðÂàÂ" >+PASS converter.testString is "\udc00\ud800" > converter.testUSVString = "ðÂÂÂ" > converter.testString = "ðÂÂÂ" > PASS converter.testUSVString is "ðÂÂÂ" >diff --git a/LayoutTests/js/resources/json2-es5-compat.js b/LayoutTests/js/resources/json2-es5-compat.js >index 047b3d490878485a328e9c870682fe288d98b892..d9e2ea4ad9018d51798b7e141ab758d79adfd6ac 100644 >--- a/LayoutTests/js/resources/json2-es5-compat.js >+++ b/LayoutTests/js/resources/json2-es5-compat.js >@@ -182,7 +182,7 @@ function f(n) { > } > > var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, >- escapable = /[\\\"\x00-\x1f]/g, >+ escapable = /[\\\"\x00-\x1f\ud800-\udbff\udc00-\udfff]/g, > gap, > indent, > meta = { // table of character substitutions >@@ -196,6 +196,18 @@ function f(n) { > }, > rep; > >+ function isHighSurrogate(code) { >+ return code >= 0xd800 && code <= 0xdbff; >+ } >+ >+ function isLowSurrogate(code) { >+ return code >= 0xdc00 && code <= 0xdfff; >+ } >+ >+ function isSurrogate(code) { >+ return isHighSurrogate(code) || isLowSurrogate(code); >+ } >+ > > function quote(string) { > >@@ -206,10 +218,21 @@ function quote(string) { > > escapable.lastIndex = 0; > return escapable.test(string) ? >- '"' + string.replace(escapable, function (a) { >+ '"' + string.replace(escapable, function (a, offset) { > var c = meta[a]; >- return typeof c === 'string' ? c : >- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); >+ if (typeof c === 'string') >+ return c; >+ var code = a.charCodeAt(0); >+ if (!isSurrogate(code)) >+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); >+ >+ if (isLowSurrogate(code) && (offset - 1) >= 0 && isHighSurrogate(string.charCodeAt(offset - 1))) >+ return a; >+ >+ if (isHighSurrogate(code) && (offset + 1) < string.length && isLowSurrogate(string.charCodeAt(offset + 1))) >+ return a; >+ >+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); > }) + '"' : > '"' + string + '"'; > } >diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog >index ebb44b0d8b0ea0741507caa55df6e9679f16ff79..36df789d96c07e00d3a10b8ce8dd40fe23e9d74b 100644 >--- a/JSTests/ChangeLog >+++ b/JSTests/ChangeLog >@@ -1,3 +1,14 @@ >+2018-12-20 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ [JSC] Implement "well-formed JSON.stringify" proposal >+ https://bugs.webkit.org/show_bug.cgi?id=191677 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * stress/json-surrogate-pair.js: Added. >+ (shouldBe): >+ * test262/expectations.yaml: >+ > 2018-12-20 Tadeu Zagallo <tzagallo@apple.com> > > WTF::String and StringImpl overflow MaxLength >diff --git a/JSTests/stress/json-surrogate-pair.js b/JSTests/stress/json-surrogate-pair.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8c309bd45909e11b0b8abde3c7370214e6eda4a7 >--- /dev/null >+++ b/JSTests/stress/json-surrogate-pair.js >@@ -0,0 +1,14 @@ >+function shouldBe(actual, expected) { >+ if (actual !== expected) >+ throw new Error('bad value: ' + actual); >+} >+ >+shouldBe(JSON.stringify('ð'), `"ð"`); >+shouldBe(JSON.stringify('\uD834\uDF06'), `"ð"`); >+shouldBe(JSON.stringify('\uD834'), `"\\ud834"`); >+shouldBe(JSON.stringify('\uDF06'), `"\\udf06"`); >+shouldBe(JSON.stringify('\uDF06\uD834'), `"\\udf06\\ud834"`); >+shouldBe(JSON.stringify('\uDEAD'), `"\\udead"`); >+shouldBe(JSON.stringify('\uD834\uD834\uDF06'), `"\\ud834ð"`); >+shouldBe(JSON.stringify('\uD834a'), `"\\ud834a"`); >+shouldBe(JSON.stringify('\uD834\u0400'), `"\\ud834Ð"`); >diff --git a/JSTests/test262/expectations.yaml b/JSTests/test262/expectations.yaml >index 23fe962adaba5db1ebd3dd9a5e47b1f88c462c61..987a4e5540681413904fefd4d87a28e178f5eb99 100644 >--- a/JSTests/test262/expectations.yaml >+++ b/JSTests/test262/expectations.yaml >@@ -1022,9 +1022,6 @@ test/built-ins/JSON/parse/reviver-array-length-coerce-err.js: > test/built-ins/JSON/parse/reviver-array-length-get-err.js: > default: 'Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all' > strict mode: 'Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all' >-test/built-ins/JSON/stringify/string-escape-unicode.js: >- default: 'Test262Error: JSON.stringify("\uD834") Expected SameValue(ë"à´"û, ë"\ud834"û) to be true' >- strict mode: 'Test262Error: JSON.stringify("\uD834") Expected SameValue(ë"à´"û, ë"\ud834"û) to be true' > test/built-ins/Map/proto-from-ctor-realm.js: > default: 'Test262Error: Expected SameValue(ë[object Map]û, ë[object Map]û) to be true' > strict mode: 'Test262Error: Expected SameValue(ë[object Map]û, ë[object Map]û) to be true'
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
darin
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 191677
:
354906
|
354907
|
354910
|
354911
|
354913
|
354915
|
355026
|
355030
|
355032
|
355033
|
355034
|
355038
|
355191
|
355192
|
355194
| 357828