Ignore:
Timestamp:
Feb 28, 2016, 10:40:35 AM (9 years ago)
Author:
[email protected]
Message:

ProxyObject.GetOwnProperty is partially broken because it doesn't propagate information back to the slot
https://bugs.webkit.org/show_bug.cgi?id=154768

Reviewed by Ryosuke Niwa.

This fixes a big bug with ProxyObject.GetOwnProperty:
http://www.ecma-international.org/ecma-262/6.0/index.html#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p
We weren't correctly propagating the result of this operation to the
out PropertySlot& parameter. This patch fixes that and adds tests.

  • runtime/ObjectConstructor.cpp:

(JSC::objectConstructorGetOwnPropertyDescriptor):
I added a missing exception check after object allocation
because I saw that it was missing while reading the code.

  • runtime/PropertyDescriptor.cpp:

(JSC::PropertyDescriptor::setUndefined):
(JSC::PropertyDescriptor::slowGetterSetter):
(JSC::PropertyDescriptor::getter):

  • runtime/PropertyDescriptor.h:

(JSC::PropertyDescriptor::attributes):
(JSC::PropertyDescriptor::value):

  • runtime/ProxyObject.cpp:

(JSC::ProxyObject::performInternalMethodGetOwnProperty):

  • tests/es6.yaml:
  • tests/stress/proxy-get-own-property.js:

(let.handler.getOwnPropertyDescriptor):
(set get let.handler.return):
(set get let.handler.getOwnPropertyDescriptor):
(set get let):
(set get let.a):
(let.b):
(let.setter):
(let.getter):

Location:
trunk/Source/JavaScriptCore/runtime
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/ObjectConstructor.cpp

    r196722 r197295  
    233233
    234234    JSObject* description = constructEmptyObject(exec);
     235    if (exec->hadException())
     236        return jsUndefined();
    235237    if (!descriptor.isAccessorDescriptor()) {
    236238        description->putDirect(exec->vm(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
  • trunk/Source/JavaScriptCore/runtime/PropertyDescriptor.cpp

    r196001 r197295  
    7373}
    7474
     75GetterSetter* PropertyDescriptor::slowGetterSetter(ExecState* exec)
     76{
     77    VM& vm = exec->vm();
     78    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     79    GetterSetter* getterSetter = GetterSetter::create(vm, globalObject);
     80    if (exec->hadException())
     81        return nullptr;
     82    if (m_getter && !m_getter.isUndefined())
     83        getterSetter->setGetter(vm, globalObject, jsCast<JSObject*>(m_getter));
     84    if (m_setter && !m_setter.isUndefined())
     85        getterSetter->setSetter(vm, globalObject, jsCast<JSObject*>(m_setter));
     86
     87    return getterSetter;
     88}
     89
    7590JSValue PropertyDescriptor::getter() const
    7691{
  • trunk/Source/JavaScriptCore/runtime/PropertyDescriptor.h

    r185768 r197295  
    6060    unsigned attributes() const { return m_attributes; }
    6161    JSValue value() const { return m_value; }
     62    GetterSetter* slowGetterSetter(ExecState*); // Be aware that this will lazily allocate a GetterSetter object. It's much better to use getter() and setter() individually if possible.
    6263    JS_EXPORT_PRIVATE JSValue getter() const;
    6364    JS_EXPORT_PRIVATE JSValue setter() const;
  • trunk/Source/JavaScriptCore/runtime/ProxyObject.cpp

    r197136 r197295  
    139139{
    140140    VM& vm = exec->vm();
    141     slot.setValue(this, None, jsUndefined()); // We do this to protect against any bad actors. Nobody should depend on this value.
    142141    JSValue handlerValue = this->handler();
    143142    if (handlerValue.isNull()) {
     
    211210        }
    212211    }
     212
     213    if (trapResultAsDescriptor.isAccessorDescriptor()) {
     214        GetterSetter* getterSetter = trapResultAsDescriptor.slowGetterSetter(exec);
     215        if (exec->hadException())
     216            return false;
     217        slot.setGetterSlot(this, trapResultAsDescriptor.attributes(), getterSetter);
     218    } else if (trapResultAsDescriptor.isDataDescriptor())
     219        slot.setValue(this, trapResultAsDescriptor.attributes(), trapResultAsDescriptor.value());
     220    else
     221        slot.setValue(this, trapResultAsDescriptor.attributes(), jsUndefined()); // We use undefined because it's the default value in object properties.
    213222
    214223    return true;
Note: See TracChangeset for help on using the changeset viewer.