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