Title: [201674] trunk
Revision
201674
Author
[email protected]
Date
2016-06-03 18:08:27 -0700 (Fri, 03 Jun 2016)

Log Message

JSON.stringify replacer function calls with numeric array indices
https://bugs.webkit.org/show_bug.cgi?id=158262
Source/_javascript_Core:

rdar://problem/26613876

Patch by Benjamin Poulain <[email protected]> on 2016-06-03
Reviewed by Saam Barati.

The spec of SerializeJSONArray is pretty clear that the index
should be transformed into a string before calling SerializeJSONProperty.
See http://www.ecma-international.org/ecma-262/6.0/#sec-serializejsonarray

* runtime/JSONObject.cpp:
(JSC::PropertyNameForFunctionCall::value):

LayoutTests:

Patch by Benjamin Poulain <[email protected]> on 2016-06-03
Reviewed by Saam Barati.

* js/JSON-stringify-exposes-array-indices-as-strings-expected.txt: Added.
* js/JSON-stringify-exposes-array-indices-as-strings.html: Added.
* js/script-tests/JSON-stringify-exposes-array-indices-as-strings.js: Added.
(replacer):
(testObject.toJSON):
(toJSONArrayHelper):
* js/resources/JSON-stringify.js:
* js/dom/JSON-stringify-expected.txt:
Update the test results for the native implementation.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (201673 => 201674)


--- trunk/LayoutTests/ChangeLog	2016-06-04 00:56:57 UTC (rev 201673)
+++ trunk/LayoutTests/ChangeLog	2016-06-04 01:08:27 UTC (rev 201674)
@@ -1,3 +1,20 @@
+2016-06-03  Benjamin Poulain  <[email protected]>
+
+        JSON.stringify replacer function calls with numeric array indices
+        https://bugs.webkit.org/show_bug.cgi?id=158262
+
+        Reviewed by Saam Barati.
+
+        * js/JSON-stringify-exposes-array-indices-as-strings-expected.txt: Added.
+        * js/JSON-stringify-exposes-array-indices-as-strings.html: Added.
+        * js/script-tests/JSON-stringify-exposes-array-indices-as-strings.js: Added.
+        (replacer):
+        (testObject.toJSON):
+        (toJSONArrayHelper):
+        * js/resources/JSON-stringify.js:
+        * js/dom/JSON-stringify-expected.txt:
+        Update the test results for the native implementation.
+
 2016-06-03  Ryosuke Niwa  <[email protected]>
 
         Crash under VisibleSelection::firstRange()

Added: trunk/LayoutTests/js/JSON-stringify-exposes-array-indices-as-strings-expected.txt (0 => 201674)


--- trunk/LayoutTests/js/JSON-stringify-exposes-array-indices-as-strings-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/JSON-stringify-exposes-array-indices-as-strings-expected.txt	2016-06-04 01:08:27 UTC (rev 201674)
@@ -0,0 +1,32 @@
+Verify that JSON.stringify passes keys as strings when calling toJSON or the replacer function.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Test Replacer Function
+PASS typeof globalKey is "string"
+PASS globalKey is ""
+PASS typeof globalValue is "object"
+PASS globalValue instanceof Array is true
+PASS globalValue.length is 1
+PASS globalValue[0] is 42
+PASS typeof globalKey is "string"
+PASS globalKey is "0"
+PASS typeof globalValue is "number"
+PASS globalValue is 42
+PASS JSON.stringify([42], replacer) is "[5]"
+
+Test toJSON Function
+PASS toJSONArrayHelperCallCounter is 0
+PASS globalThis === testArray is true
+PASS typeof globalKey is "string"
+PASS globalKey is ""
+PASS toJSONArrayHelperCallCounter is 1
+PASS globalThis === testObject is true
+PASS typeof globalKey is "string"
+PASS globalKey is "0"
+PASS JSON.stringify(testArray) is "[true]"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/JSON-stringify-exposes-array-indices-as-strings.html (0 => 201674)


--- trunk/LayoutTests/js/JSON-stringify-exposes-array-indices-as-strings.html	                        (rev 0)
+++ trunk/LayoutTests/js/JSON-stringify-exposes-array-indices-as-strings.html	2016-06-04 01:08:27 UTC (rev 201674)
@@ -0,0 +1,10 @@
+<!DOCTYPE>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/LayoutTests/js/dom/JSON-stringify-expected.txt (201673 => 201674)


--- trunk/LayoutTests/js/dom/JSON-stringify-expected.txt	2016-06-04 00:56:57 UTC (rev 201673)
+++ trunk/LayoutTests/js/dom/JSON-stringify-expected.txt	2016-06-04 01:08:27 UTC (rev 201674)
@@ -147,7 +147,7 @@
         jsonObject.stringify([1,2,3,4,5], function(k,v){allString = allString && (typeof k == "string"); return v});
         return allString;
     }
-PASS tests[i](nativeJSON) is tests[i](JSON)
+PASS tests[i](nativeJSON) is tests[i].expected
 function (jsonObject){
         var allString = true;
         var array = [];

Modified: trunk/LayoutTests/js/resources/JSON-stringify.js (201673 => 201674)


--- trunk/LayoutTests/js/resources/JSON-stringify.js	2016-06-04 00:56:57 UTC (rev 201673)
+++ trunk/LayoutTests/js/resources/JSON-stringify.js	2016-06-04 01:08:27 UTC (rev 201674)
@@ -144,6 +144,7 @@
         jsonObject.stringify([1,2,3,4,5], function(k,v){allString = allString && (typeof k == "string"); return v});
         return allString;
     });
+    result[result.length - 1].expected = true;
     result.push(function(jsonObject){
         var allString = true;
         var array = [];
@@ -346,7 +347,7 @@
         jsonObject.stringify([1,2,3,,,,4,5,6], replaceFunc);
         return replaceTracker;
     });
-    result[result.length - 1].expected = '(string)[1,2,3,null,null,null,4,5,6];0(number)1;1(number)2;2(number)3;3(number)undefined;4(number)undefined;5(number)undefined;6(number)4;7(number)5;8(number)6;'
+    result[result.length - 1].expected = '(string)[1,2,3,null,null,null,4,5,6];0(string)1;1(string)2;2(string)3;3(string)undefined;4(string)undefined;5(string)undefined;6(string)4;7(string)5;8(string)6;'
     result.push(function(jsonObject){
         replaceTracker = "";
         jsonObject.stringify({a:"a", b:"b", c:"c", 3: "d", 2: "e", 1: "f"}, replaceFunc);
@@ -427,7 +428,7 @@
         try { jsonObject.stringify(cyclicArray); } catch(e) { cycleTracker += " -> exception" }
         return cycleTracker;
     });
-    result[result.length - 1].expected = "0(number):[object Object]first, -> exception";
+    result[result.length - 1].expected = "0(string):[object Object]first, -> exception";
     function createArray(len, o) { var r = []; for (var i = 0; i < len; i++) r[i] = o; return r; }
     var getterCalls;
     var magicObject = createArray(10, {abcdefg: [1,2,5,"ab", null, undefined, true, false,,], 

Added: trunk/LayoutTests/js/script-tests/JSON-stringify-exposes-array-indices-as-strings.js (0 => 201674)


--- trunk/LayoutTests/js/script-tests/JSON-stringify-exposes-array-indices-as-strings.js	                        (rev 0)
+++ trunk/LayoutTests/js/script-tests/JSON-stringify-exposes-array-indices-as-strings.js	2016-06-04 01:08:27 UTC (rev 201674)
@@ -0,0 +1,64 @@
+"use strict";
+
+description("Verify that JSON.stringify passes keys as strings when calling toJSON or the replacer function.");
+
+debug("Test Replacer Function");
+var globalKey;
+var globalValue;
+var globalIndex = 0;
+function replacer(key, value) {
+    globalKey = key;
+    globalValue = value;
+    if (globalIndex == 0) {
+        shouldBeEqualToString("typeof globalKey", "string");
+        shouldBeEqualToString("globalKey", "");
+        shouldBeEqualToString("typeof globalValue", "object");
+        shouldBeTrue("globalValue instanceof Array");
+        shouldBe("globalValue.length", "1");
+        shouldBe("globalValue[0]", "42");
+    } else if (globalIndex == 1) {
+        globalKey = key;
+        shouldBeEqualToString("typeof globalKey", "string");
+        shouldBeEqualToString("globalKey", "0");
+        shouldBeEqualToString("typeof globalValue", "number");
+        shouldBe("globalValue", "42");
+        value = 5;
+    } else {
+        shouldBeTrue(false);
+    }
+    ++globalIndex;
+    return value;
+}
+
+shouldBeEqualToString("JSON.stringify([42], replacer)", "[5]");
+
+debug("");
+debug("Test toJSON Function");
+var globalThis;
+var toJSONArrayHelperCallCounter = 0;
+var testObject = {
+    toJSON: function(key) {
+        globalThis = this;
+        globalKey = key;
+        shouldBe("toJSONArrayHelperCallCounter", "1");
+        shouldBeTrue("globalThis === testObject");
+        shouldBeEqualToString("typeof globalKey", "string");
+        shouldBeEqualToString("globalKey", "0");
+        return true;
+    }
+}
+
+var testArray = [testObject];
+function toJSONArrayHelper(key) {
+    globalThis = this;
+    globalKey = key;
+    shouldBe("toJSONArrayHelperCallCounter", "0");
+    shouldBeTrue("globalThis === testArray");
+    shouldBeEqualToString("typeof globalKey", "string");
+    shouldBeEqualToString("globalKey", "");
+    ++toJSONArrayHelperCallCounter;
+    return this;
+}
+
+Array.prototype.toJSON = toJSONArrayHelper;
+shouldBeEqualToString("JSON.stringify(testArray)", "[true]");

Modified: trunk/Source/_javascript_Core/ChangeLog (201673 => 201674)


--- trunk/Source/_javascript_Core/ChangeLog	2016-06-04 00:56:57 UTC (rev 201673)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-06-04 01:08:27 UTC (rev 201674)
@@ -1,3 +1,18 @@
+2016-06-03  Benjamin Poulain  <[email protected]>
+
+        JSON.stringify replacer function calls with numeric array indices
+        https://bugs.webkit.org/show_bug.cgi?id=158262
+        rdar://problem/26613876
+
+        Reviewed by Saam Barati.
+
+        The spec of SerializeJSONArray is pretty clear that the index
+        should be transformed into a string before calling SerializeJSONProperty.
+        See http://www.ecma-international.org/ecma-262/6.0/#sec-serializejsonarray
+
+        * runtime/JSONObject.cpp:
+        (JSC::PropertyNameForFunctionCall::value):
+
 2016-06-03  Saam barati  <[email protected]>
 
         Proxy.ownKeys should no longer throw an exception when duplicate keys are returned and the target is non-extensible

Modified: trunk/Source/_javascript_Core/runtime/JSONObject.cpp (201673 => 201674)


--- trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2016-06-04 00:56:57 UTC (rev 201673)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.cpp	2016-06-04 01:08:27 UTC (rev 201674)
@@ -200,8 +200,12 @@
     if (!m_value) {
         if (m_identifier)
             m_value = jsString(exec, m_identifier->string());
-        else
-            m_value = jsNumber(m_number);
+        else {
+            VM& vm = exec->vm();
+            if (m_number <= 9)
+                return vm.smallStrings.singleCharacterString(m_number + '0');
+            m_value = jsNontrivialString(&vm, vm.numericStrings.add(m_number));
+        }
     }
     return m_value;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to