Changeset 260447 in webkit


Ignore:
Timestamp:
Apr 21, 2020 12:18:36 PM (4 years ago)
Author:
Alexey Shvayka
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/JavaScriptCore:

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

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r260443 r260447  
     12020-04-21  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        constructObjectFromPropertyDescriptor() is incorrect with partial descriptors
     4        https://bugs.webkit.org/show_bug.cgi?id=184629
     5
     6        Reviewed by Ross Kirsling.
     7
     8        * test262/expectations.yaml: Mark 4 test cases as passing.
     9
    1102020-04-21  Yusuke Suzuki  <ysuzuki@apple.com>
    211
  • trunk/JSTests/test262/expectations.yaml

    r260349 r260447  
    12471247  default: 'Test262Error: Expected [length, foo, 0, Symbol()] and [Symbol(), length, foo, 0] to have the same contents. '
    12481248  strict mode: 'Test262Error: Expected [length, foo, 0, Symbol()] and [Symbol(), length, foo, 0] to have the same contents. '
    1249 test/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls-index.js:
    1250   default: 'Test262Error: Expected [0] and [0, 0, 0] to have the same contents. getOwnPropertyDescriptor: key present on [[ProxyTarget]]'
    1251   strict mode: 'TypeError: Attempted to assign to readonly property.'
    1252 test/built-ins/Proxy/set/trap-is-missing-receiver-multiple-calls.js:
    1253   default: 'Test262Error: Expected [foo] and [foo, foo, foo] to have the same contents. getOwnPropertyDescriptor: key present on [[ProxyTarget]]'
    1254   strict mode: 'TypeError: Attempted to assign to readonly property.'
    12551249test/built-ins/Reflect/ownKeys/order-after-define-property.js:
    12561250  default: 'Test262Error: Expected [Symbol(b), Symbol(a)] and [Symbol(a), Symbol(b)] to have the same contents. '
  • trunk/Source/JavaScriptCore/ChangeLog

    r260434 r260447  
     12020-04-21  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        constructObjectFromPropertyDescriptor() is incorrect with partial descriptors
     4        https://bugs.webkit.org/show_bug.cgi?id=184629
     5
     6        Reviewed by Ross Kirsling.
     7
     8        Before this change, constructObjectFromPropertyDescriptor() serialized a value-only descriptor
     9        with nullish m_seenAttributes to {value, writable: false, enumerable: false, configurable: false}
     10        instead of just {value}. This was observable when ordinarySetSlow() was called on a Proxy
     11        `receiver` with "defineProperty" trap.
     12
     13        This patch makes constructObjectFromPropertyDescriptor() 1:1 with the spec [2], aligning JSC
     14        with V8 and SpiderMonkey, and also cleans up its call sites from handling exceptions and
     15        `undefined` value returns.
     16
     17        [1]: https://tc39.es/ecma262/#sec-ordinarysetwithowndescriptor (step 3.d.iv)
     18        [2]: https://tc39.es/ecma262/#sec-frompropertydescriptor
     19
     20        * runtime/ObjectConstructor.cpp:
     21        (JSC::objectConstructorGetOwnPropertyDescriptor):
     22        (JSC::objectConstructorGetOwnPropertyDescriptors):
     23        * runtime/ObjectConstructor.h:
     24        (JSC::constructObjectFromPropertyDescriptor):
     25        * runtime/ProxyObject.cpp:
     26        (JSC::ProxyObject::performDefineOwnProperty):
     27
    1282020-04-20  Yusuke Suzuki  <ysuzuki@apple.com>
    229
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r260434 r260447  
    192192
    193193    JSObject* result = constructObjectFromPropertyDescriptor(globalObject, descriptor);
    194     EXCEPTION_ASSERT(!!scope.exception() == !result);
    195     if (!result)
    196         return jsUndefined();
     194    scope.assertNoException();
     195    ASSERT(result);
    197196    return result;
    198197}
     
    218217
    219218        JSObject* fromDescriptor = constructObjectFromPropertyDescriptor(globalObject, descriptor);
    220         EXCEPTION_ASSERT(!!scope.exception() == !fromDescriptor);
    221         if (!fromDescriptor)
    222             return jsUndefined();
     219        scope.assertNoException();
     220        ASSERT(fromDescriptor);
    223221
    224222        PutPropertySlot slot(descriptors);
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.h

    r260415 r260447  
    9090}
    9191
    92 // Section 6.2.4.4 of the ES6 specification.
    93 // https://tc39.github.io/ecma262/#sec-frompropertydescriptor
     92// https://tc39.es/ecma262/#sec-frompropertydescriptor
    9493inline JSObject* constructObjectFromPropertyDescriptor(JSGlobalObject* globalObject, const PropertyDescriptor& descriptor)
    9594{
    9695    VM& vm = getVM(globalObject);
    97     auto scope = DECLARE_THROW_SCOPE(vm);
    98     JSObject* description = constructEmptyObject(globalObject);
    99     RETURN_IF_EXCEPTION(scope, nullptr);
     96    JSObject* result = constructEmptyObject(globalObject);
    10097
    101     if (!descriptor.isAccessorDescriptor()) {
    102         description->putDirect(vm, vm.propertyNames->value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
    103         description->putDirect(vm, vm.propertyNames->writable, jsBoolean(descriptor.writable()), 0);
    104     } else {
    105         ASSERT(descriptor.getter() || descriptor.setter());
    106         if (descriptor.getter())
    107             description->putDirect(vm, vm.propertyNames->get, descriptor.getter(), 0);
    108         if (descriptor.setter())
    109             description->putDirect(vm, vm.propertyNames->set, descriptor.setter(), 0);
    110     }
    111    
    112     description->putDirect(vm, vm.propertyNames->enumerable, jsBoolean(descriptor.enumerable()), 0);
    113     description->putDirect(vm, vm.propertyNames->configurable, jsBoolean(descriptor.configurable()), 0);
     98    if (descriptor.value())
     99        result->putDirect(vm, vm.propertyNames->value, descriptor.value());
     100    if (descriptor.writablePresent())
     101        result->putDirect(vm, vm.propertyNames->writable, jsBoolean(descriptor.writable()));
     102    if (descriptor.getterPresent())
     103        result->putDirect(vm, vm.propertyNames->get, descriptor.getter());
     104    if (descriptor.setterPresent())
     105        result->putDirect(vm, vm.propertyNames->set, descriptor.setter());
     106    if (descriptor.enumerablePresent())
     107        result->putDirect(vm, vm.propertyNames->enumerable, jsBoolean(descriptor.enumerable()));
     108    if (descriptor.configurablePresent())
     109        result->putDirect(vm, vm.propertyNames->configurable, jsBoolean(descriptor.configurable()));
    114110
    115     return description;
     111    return result;
    116112}
    117113
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp

    r259822 r260447  
    853853
    854854    JSObject* descriptorObject = constructObjectFromPropertyDescriptor(globalObject, descriptor);
    855     RETURN_IF_EXCEPTION(scope, false);
     855    scope.assertNoException();
     856    ASSERT(descriptorObject);
    856857
    857858    MarkedArgumentBuffer arguments;
Note: See TracChangeset for help on using the changeset viewer.