- Revision
- 264833
- Author
- [email protected]
- Date
- 2020-07-24 09:42:50 -0700 (Fri, 24 Jul 2020)
Log Message
JSON.parse should not modify non-configurable properties.
https://bugs.webkit.org/show_bug.cgi?id=163446
Reviewed by Darin Adler.
JSTests:
* test262/expectations.yaml: Mark 2 test cases as passing.
Source/_javascript_Core:
This change implements step 2.c.ii.3 of InternalizeJSONProperty [1], replacing
put() with defineOwnProperty(). Using the latter fixes JSON.parse() with
non-configurable (failures are silently ignored; see note in the spec),
non-writable, and accessor properties, aligning JSC with V8 and SpiderMonkey.
Since it's extremely unlikely for userland `reviver` to remove or redefine the
next property, a fast path for PropertyAttribute::None attributes is introduced.
It advances microbenchmarks/json-parse-object-*.js by ~13%.
[1]: https://tc39.es/ecma262/#sec-internalizejsonproperty
* runtime/JSONObject.cpp:
(JSC::Walker::walk):
Modified Paths
Diff
Modified: trunk/JSTests/ChangeLog (264832 => 264833)
--- trunk/JSTests/ChangeLog 2020-07-24 16:40:52 UTC (rev 264832)
+++ trunk/JSTests/ChangeLog 2020-07-24 16:42:50 UTC (rev 264833)
@@ -1,3 +1,12 @@
+2020-07-24 Alexey Shvayka <[email protected]>
+
+ JSON.parse should not modify non-configurable properties.
+ https://bugs.webkit.org/show_bug.cgi?id=163446
+
+ Reviewed by Darin Adler.
+
+ * test262/expectations.yaml: Mark 2 test cases as passing.
+
2020-07-24 Yusuke Suzuki <[email protected]>
[JSC] Do not use hardened Array for Intl supportedLocalesOf
Modified: trunk/JSTests/test262/expectations.yaml (264832 => 264833)
--- trunk/JSTests/test262/expectations.yaml 2020-07-24 16:40:52 UTC (rev 264832)
+++ trunk/JSTests/test262/expectations.yaml 2020-07-24 16:42:50 UTC (rev 264833)
@@ -900,9 +900,6 @@
test/built-ins/Function/prototype/toString/unicode.js:
default: "Test262Error: Conforms to NativeFunction Syntax: 'function a(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; }'.(function \\u0061(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; })"
strict mode: "Test262Error: Conforms to NativeFunction Syntax: 'function a(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; }'.(function \\u0061(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; })"
-test/built-ins/JSON/parse/reviver-object-non-configurable-prop-create.js:
- default: 'Test262Error: Expected SameValue(«22», «2») to be true'
- strict mode: 'Test262Error: Expected SameValue(«22», «2») to be true'
test/built-ins/Object/assign/strings-and-symbol-order-proxy.js:
default: 'Test262Error: Expected [foo, 0, Symbol()] and [Symbol(), foo, 0] to have the same contents. '
strict mode: 'Test262Error: Expected [foo, 0, Symbol()] and [Symbol(), foo, 0] to have the same contents. '
Modified: trunk/Source/_javascript_Core/ChangeLog (264832 => 264833)
--- trunk/Source/_javascript_Core/ChangeLog 2020-07-24 16:40:52 UTC (rev 264832)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-07-24 16:42:50 UTC (rev 264833)
@@ -1,3 +1,24 @@
+2020-07-24 Alexey Shvayka <[email protected]>
+
+ JSON.parse should not modify non-configurable properties.
+ https://bugs.webkit.org/show_bug.cgi?id=163446
+
+ Reviewed by Darin Adler.
+
+ This change implements step 2.c.ii.3 of InternalizeJSONProperty [1], replacing
+ put() with defineOwnProperty(). Using the latter fixes JSON.parse() with
+ non-configurable (failures are silently ignored; see note in the spec),
+ non-writable, and accessor properties, aligning JSC with V8 and SpiderMonkey.
+
+ Since it's extremely unlikely for userland `reviver` to remove or redefine the
+ next property, a fast path for PropertyAttribute::None attributes is introduced.
+ It advances microbenchmarks/json-parse-object-*.js by ~13%.
+
+ [1]: https://tc39.es/ecma262/#sec-internalizejsonproperty
+
+ * runtime/JSONObject.cpp:
+ (JSC::Walker::walk):
+
2020-07-24 Yusuke Suzuki <[email protected]>
[JSC] Do not use hardened Array for Intl supportedLocalesOf
Modified: trunk/Source/_javascript_Core/runtime/JSONObject.cpp (264832 => 264833)
--- trunk/Source/_javascript_Core/runtime/JSONObject.cpp 2020-07-24 16:40:52 UTC (rev 264832)
+++ trunk/Source/_javascript_Core/runtime/JSONObject.cpp 2020-07-24 16:42:50 UTC (rev 264833)
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009-2020 Apple Inc. All rights reserved.
+ * Copyright (C) 2020 Alexey Shvayka <[email protected]>.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -748,13 +749,21 @@
case ObjectEndVisitMember: {
JSObject* object = jsCast<JSObject*>(markedStack.last());
Identifier prop = propertyStack.last()[indexStack.last()];
- PutPropertySlot slot(object);
JSValue filteredValue = callReviver(object, jsString(vm, prop.string()), outValue);
RETURN_IF_EXCEPTION(scope, { });
if (filteredValue.isUndefined())
JSCell::deleteProperty(object, m_globalObject, prop);
- else
- object->methodTable(vm)->put(object, m_globalObject, prop, filteredValue, slot);
+ else {
+ unsigned attributes;
+ PropertyOffset offset = object->getDirectOffset(vm, prop, attributes);
+ if (LIKELY(offset != invalidOffset && attributes == static_cast<unsigned>(PropertyAttribute::None)))
+ object->putDirect(vm, offset, filteredValue);
+ else {
+ PropertyDescriptor descriptor(filteredValue, static_cast<unsigned>(PropertyAttribute::None));
+ bool shouldThrow = false;
+ object->methodTable(vm)->defineOwnProperty(object, m_globalObject, prop, descriptor, shouldThrow);
+ }
+ }
RETURN_IF_EXCEPTION(scope, { });
indexStack.last()++;
goto objectStartVisitMember;