Title: [260447] trunk
Revision
260447
Author
shvaikal...@gmail.com
Date
2020-04-21 12:18:36 -0700 (Tue, 21 Apr 2020)

Log Message

constructObjectFromPropertyDescriptor() is incorrect with partial descriptors
https://bugs.webkit.org/show_bug.cgi?id=184629

Reviewed by Ross Kirsling.

JSTests:

* test262/expectations.yaml: Mark 4 test cases as passing.

Source/_javascript_Core:

Before this change, constructObjectFromPropertyDescriptor() serialized a value-only descriptor
with nullish m_seenAttributes to {value, writable: false, enumerable: false, configurable: false}
instead of just {value}. This was observable when ordinarySetSlow() was called on a Proxy
`receiver` with "defineProperty" trap.

This patch makes constructObjectFromPropertyDescriptor() 1:1 with the spec [2], aligning JSC
with V8 and SpiderMonkey, and also cleans up its call sites from handling exceptions and
`undefined` value returns.

[1]: https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor (step 3.d.iv)
[2]: https://tc39.es/ecma262/#sec-frompropertydescriptor

* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorGetOwnPropertyDescriptor):
(JSC::objectConstructorGetOwnPropertyDescriptors):
* runtime/ObjectConstructor.h:
(JSC::constructObjectFromPropertyDescriptor):
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::performDefineOwnProperty):

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (260446 => 260447)


--- trunk/JSTests/ChangeLog	2020-04-21 18:42:45 UTC (rev 260446)
+++ trunk/JSTests/ChangeLog	2020-04-21 19:18:36 UTC (rev 260447)
@@ -1,3 +1,12 @@
+2020-04-21  Alexey Shvayka  <shvaikal...@gmail.com>
+
+        constructObjectFromPropertyDescriptor() is incorrect with partial descriptors
+        https://bugs.webkit.org/show_bug.cgi?id=184629
+
+        Reviewed by Ross Kirsling.
+
+        * test262/expectations.yaml: Mark 4 test cases as passing.
+
 2020-04-21  Yusuke Suzuki  <ysuz...@apple.com>
 
         Move value-pow-ai-rule-should-box-the-same-way-as-the-runtime.js to JSTests/stress/

Modified: trunk/JSTests/test262/expectations.yaml (260446 => 260447)


--- trunk/JSTests/test262/expectations.yaml	2020-04-21 18:42:45 UTC (rev 260446)
+++ trunk/JSTests/test262/expectations.yaml	2020-04-21 19:18:36 UTC (rev 260447)
@@ -1246,12 +1246,6 @@
 test/built-ins/Proxy/ownKeys/trap-is-undefined-target-is-proxy.js:
   default: 'Test262Error: Expected [length, foo, 0, Symbol()] and [Symbol(), length, foo, 0] to have the same contents. '
   strict mode: 'Test262Error: Expected [length, foo, 0, Symbol()] and [Symbol(), length, foo, 0] to have the same contents. '
-test/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js:
-  default: 'Test262Error: Expected [0] and [0, 0, 0] to have the same contents. getOwnPropertyDescriptor: key present on [[ProxyTarget]]'
-  strict mode: 'TypeError: Attempted to assign to readonly property.'
-test/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js:
-  default: 'Test262Error: Expected [foo] and [foo, foo, foo] to have the same contents. getOwnPropertyDescriptor: key present on [[ProxyTarget]]'
-  strict mode: 'TypeError: Attempted to assign to readonly property.'
 test/built-ins/Reflect/ownKeys/order-after-define-property.js:
   default: 'Test262Error: Expected [Symbol(b), Symbol(a)] and [Symbol(a), Symbol(b)] to have the same contents. '
   strict mode: 'Test262Error: Expected [Symbol(b), Symbol(a)] and [Symbol(a), Symbol(b)] to have the same contents. '

Modified: trunk/Source/_javascript_Core/ChangeLog (260446 => 260447)


--- trunk/Source/_javascript_Core/ChangeLog	2020-04-21 18:42:45 UTC (rev 260446)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-04-21 19:18:36 UTC (rev 260447)
@@ -1,3 +1,30 @@
+2020-04-21  Alexey Shvayka  <shvaikal...@gmail.com>
+
+        constructObjectFromPropertyDescriptor() is incorrect with partial descriptors
+        https://bugs.webkit.org/show_bug.cgi?id=184629
+
+        Reviewed by Ross Kirsling.
+
+        Before this change, constructObjectFromPropertyDescriptor() serialized a value-only descriptor
+        with nullish m_seenAttributes to {value, writable: false, enumerable: false, configurable: false}
+        instead of just {value}. This was observable when ordinarySetSlow() was called on a Proxy
+        `receiver` with "defineProperty" trap.
+
+        This patch makes constructObjectFromPropertyDescriptor() 1:1 with the spec [2], aligning JSC
+        with V8 and SpiderMonkey, and also cleans up its call sites from handling exceptions and
+        `undefined` value returns.
+
+        [1]: https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor (step 3.d.iv)
+        [2]: https://tc39.es/ecma262/#sec-frompropertydescriptor
+
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorGetOwnPropertyDescriptor):
+        (JSC::objectConstructorGetOwnPropertyDescriptors):
+        * runtime/ObjectConstructor.h:
+        (JSC::constructObjectFromPropertyDescriptor):
+        * runtime/ProxyObject.cpp:
+        (JSC::ProxyObject::performDefineOwnProperty):
+
 2020-04-20  Yusuke Suzuki  <ysuz...@apple.com>
 
         Check Structure attributes in Object.assign exhaustively

Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp (260446 => 260447)


--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2020-04-21 18:42:45 UTC (rev 260446)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2020-04-21 19:18:36 UTC (rev 260447)
@@ -191,9 +191,8 @@
     RETURN_IF_EXCEPTION(scope, { });
 
     JSObject* result = constructObjectFromPropertyDescriptor(globalObject, descriptor);
-    EXCEPTION_ASSERT(!!scope.exception() == !result);
-    if (!result)
-        return jsUndefined();
+    scope.assertNoException();
+    ASSERT(result);
     return result;
 }
 
@@ -217,9 +216,8 @@
             continue;
 
         JSObject* fromDescriptor = constructObjectFromPropertyDescriptor(globalObject, descriptor);
-        EXCEPTION_ASSERT(!!scope.exception() == !fromDescriptor);
-        if (!fromDescriptor)
-            return jsUndefined();
+        scope.assertNoException();
+        ASSERT(fromDescriptor);
 
         PutPropertySlot slot(descriptors);
         descriptors->putOwnDataPropertyMayBeIndex(globalObject, propertyName, fromDescriptor, slot);

Modified: trunk/Source/_javascript_Core/runtime/ObjectConstructor.h (260446 => 260447)


--- trunk/Source/_javascript_Core/runtime/ObjectConstructor.h	2020-04-21 18:42:45 UTC (rev 260446)
+++ trunk/Source/_javascript_Core/runtime/ObjectConstructor.h	2020-04-21 19:18:36 UTC (rev 260447)
@@ -89,30 +89,26 @@
     return arg.toObject(globalObject);
 }
 
-// Section 6.2.4.4 of the ES6 specification.
-// https://tc39.github.io/ecma262/#sec-frompropertydescriptor
+// https://tc39.es/ecma262/#sec-frompropertydescriptor
 inline JSObject* constructObjectFromPropertyDescriptor(JSGlobalObject* globalObject, const PropertyDescriptor& descriptor)
 {
     VM& vm = getVM(globalObject);
-    auto scope = DECLARE_THROW_SCOPE(vm);
-    JSObject* description = constructEmptyObject(globalObject);
-    RETURN_IF_EXCEPTION(scope, nullptr);
+    JSObject* result = constructEmptyObject(globalObject);
 
-    if (!descriptor.isAccessorDescriptor()) {
-        description->putDirect(vm, vm.propertyNames->value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
-        description->putDirect(vm, vm.propertyNames->writable, jsBoolean(descriptor.writable()), 0);
-    } else {
-        ASSERT(descriptor.getter() || descriptor.setter());
-        if (descriptor.getter())
-            description->putDirect(vm, vm.propertyNames->get, descriptor.getter(), 0);
-        if (descriptor.setter())
-            description->putDirect(vm, vm.propertyNames->set, descriptor.setter(), 0);
-    }
-    
-    description->putDirect(vm, vm.propertyNames->enumerable, jsBoolean(descriptor.enumerable()), 0);
-    description->putDirect(vm, vm.propertyNames->configurable, jsBoolean(descriptor.configurable()), 0);
+    if (descriptor.value())
+        result->putDirect(vm, vm.propertyNames->value, descriptor.value());
+    if (descriptor.writablePresent())
+        result->putDirect(vm, vm.propertyNames->writable, jsBoolean(descriptor.writable()));
+    if (descriptor.getterPresent())
+        result->putDirect(vm, vm.propertyNames->get, descriptor.getter());
+    if (descriptor.setterPresent())
+        result->putDirect(vm, vm.propertyNames->set, descriptor.setter());
+    if (descriptor.enumerablePresent())
+        result->putDirect(vm, vm.propertyNames->enumerable, jsBoolean(descriptor.enumerable()));
+    if (descriptor.configurablePresent())
+        result->putDirect(vm, vm.propertyNames->configurable, jsBoolean(descriptor.configurable()));
 
-    return description;
+    return result;
 }
 
 

Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.cpp (260446 => 260447)


--- trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2020-04-21 18:42:45 UTC (rev 260446)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2020-04-21 19:18:36 UTC (rev 260447)
@@ -852,7 +852,8 @@
         return performDefaultDefineOwnProperty();
 
     JSObject* descriptorObject = constructObjectFromPropertyDescriptor(globalObject, descriptor);
-    RETURN_IF_EXCEPTION(scope, false);
+    scope.assertNoException();
+    ASSERT(descriptorObject);
 
     MarkedArgumentBuffer arguments;
     arguments.append(target);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to