Title: [264833] trunk
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;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to