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;
}