Changeset 246040 in webkit


Ignore:
Timestamp:
Jun 3, 2019 11:27:46 AM (5 years ago)
Author:
ysuzuki@apple.com
Message:

[JSC] JSObject::attemptToInterceptPutByIndexOnHole should use getPrototype instead of getPrototypeDirect
https://bugs.webkit.org/show_bug.cgi?id=198477
<rdar://problem/51299504>

Reviewed by Saam Barati.

Source/JavaScriptCore:

JSObject::attemptToInterceptPutByIndexOnHole uses getPrototypeDirect, but it should use getPrototype to
handle getPrototype methods in derived JSObject classes correctly.

  • runtime/JSArrayInlines.h:

(JSC::JSArray::pushInline):

  • runtime/JSObject.cpp:

(JSC::JSObject::putByIndex):
(JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
(JSC::JSObject::attemptToInterceptPutByIndexOnHole):
(JSC::JSObject::putByIndexBeyondVectorLength):

LayoutTests:

Ensure that JSWindow::getPrototype is used.

  • http/tests/security/cross-frame-access-object-getPrototypeOf-in-put-expected.txt: Added.
  • http/tests/security/cross-frame-access-object-getPrototypeOf-in-put.html: Added.
  • http/tests/security/resources/cross-frame-iframe-for-object-getPrototypeOf-in-put-test.html: Added.
Location:
trunk
Files:
3 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r246037 r246040  
     12019-06-03  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] JSObject::attemptToInterceptPutByIndexOnHole should use getPrototype instead of getPrototypeDirect
     4        https://bugs.webkit.org/show_bug.cgi?id=198477
     5        <rdar://problem/51299504>
     6
     7        Reviewed by Saam Barati.
     8
     9        Ensure that JSWindow::getPrototype is used.
     10
     11        * http/tests/security/cross-frame-access-object-getPrototypeOf-in-put-expected.txt: Added.
     12        * http/tests/security/cross-frame-access-object-getPrototypeOf-in-put.html: Added.
     13        * http/tests/security/resources/cross-frame-iframe-for-object-getPrototypeOf-in-put-test.html: Added.
     14
    1152019-06-03  Devin Rousso  <drousso@apple.com>
    216
  • trunk/Source/JavaScriptCore/ChangeLog

    r246039 r246040  
     12019-06-03  Yusuke Suzuki  <ysuzuki@apple.com>
     2
     3        [JSC] JSObject::attemptToInterceptPutByIndexOnHole should use getPrototype instead of getPrototypeDirect
     4        https://bugs.webkit.org/show_bug.cgi?id=198477
     5        <rdar://problem/51299504>
     6
     7        Reviewed by Saam Barati.
     8
     9        JSObject::attemptToInterceptPutByIndexOnHole uses getPrototypeDirect, but it should use getPrototype to
     10        handle getPrototype methods in derived JSObject classes correctly.
     11
     12        * runtime/JSArrayInlines.h:
     13        (JSC::JSArray::pushInline):
     14        * runtime/JSObject.cpp:
     15        (JSC::JSObject::putByIndex):
     16        (JSC::JSObject::attemptToInterceptPutByIndexOnHoleForPrototype):
     17        (JSC::JSObject::attemptToInterceptPutByIndexOnHole):
     18        (JSC::JSObject::putByIndexBeyondVectorLength):
     19
    1202019-06-03  Don Olmstead  <don.olmstead@sony.com>
    221
  • trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h

    r237447 r246040  
    213213        unsigned oldLength = length();
    214214        bool putResult = false;
    215         if (attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true, putResult)) {
    216             if (!scope.exception() && oldLength < 0xFFFFFFFFu) {
     215        bool result = attemptToInterceptPutByIndexOnHole(exec, oldLength, value, true, putResult);
     216        RETURN_IF_EXCEPTION(scope, void());
     217        if (result) {
     218            if (oldLength < 0xFFFFFFFFu) {
    217219                scope.release();
    218220                setLength(exec, oldLength + 1, true);
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r245249 r246040  
    944944        WriteBarrier<Unknown>& valueSlot = storage->m_vector[propertyName];
    945945        unsigned length = storage->length();
     946
     947        auto scope = DECLARE_THROW_SCOPE(vm);
    946948       
    947949        // Update length & m_numValuesInVector as necessary.
    948950        if (propertyName >= length) {
    949951            bool putResult = false;
    950             if (thisObject->attemptToInterceptPutByIndexOnHole(exec, propertyName, value, shouldThrow, putResult))
     952            bool result = thisObject->attemptToInterceptPutByIndexOnHole(exec, propertyName, value, shouldThrow, putResult);
     953            RETURN_IF_EXCEPTION(scope, false);
     954            if (result)
    951955                return putResult;
    952956            length = propertyName + 1;
     
    955959        } else if (!valueSlot) {
    956960            bool putResult = false;
    957             if (thisObject->attemptToInterceptPutByIndexOnHole(exec, propertyName, value, shouldThrow, putResult))
     961            bool result = thisObject->attemptToInterceptPutByIndexOnHole(exec, propertyName, value, shouldThrow, putResult);
     962            RETURN_IF_EXCEPTION(scope, false);
     963            if (result)
    958964                return putResult;
    959965            ++storage->m_numValuesInVector;
     
    27172723{
    27182724    VM& vm = exec->vm();
     2725    auto scope = DECLARE_THROW_SCOPE(vm);
     2726
    27192727    for (JSObject* current = this; ;) {
    27202728        // This has the same behavior with respect to prototypes as JSObject::put(). It only
     
    27272735            SparseArrayValueMap::iterator iter = storage->m_sparseMap->find(i);
    27282736            if (iter != storage->m_sparseMap->notFound() && (iter->value.attributes() & (PropertyAttribute::Accessor | PropertyAttribute::ReadOnly))) {
     2737                scope.release();
    27292738                putResult = iter->value.put(exec, thisValue, storage->m_sparseMap.get(), value, shouldThrow);
    27302739                return true;
     
    27332742
    27342743        if (current->type() == ProxyObjectType) {
     2744            scope.release();
    27352745            ProxyObject* proxy = jsCast<ProxyObject*>(current);
    27362746            putResult = proxy->putByIndexCommon(exec, thisValue, i, value, shouldThrow);
     
    27382748        }
    27392749       
    2740         JSValue prototypeValue = current->getPrototypeDirect(vm);
     2750        JSValue prototypeValue = current->getPrototype(vm, exec);
     2751        RETURN_IF_EXCEPTION(scope, false);
    27412752        if (prototypeValue.isNull())
    27422753            return false;
     
    27482759bool JSObject::attemptToInterceptPutByIndexOnHole(ExecState* exec, unsigned i, JSValue value, bool shouldThrow, bool& putResult)
    27492760{
    2750     JSValue prototypeValue = getPrototypeDirect(exec->vm());
     2761    VM& vm = exec->vm();
     2762    auto scope = DECLARE_THROW_SCOPE(vm);
     2763
     2764    JSValue prototypeValue = getPrototype(vm, exec);
     2765    RETURN_IF_EXCEPTION(scope, false);
    27512766    if (prototypeValue.isNull())
    27522767        return false;
    27532768   
    2754     return asObject(prototypeValue)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, this, i, value, shouldThrow, putResult);
     2769    RELEASE_AND_RETURN(scope, asObject(prototypeValue)->attemptToInterceptPutByIndexOnHoleForPrototype(exec, this, i, value, shouldThrow, putResult));
    27552770}
    27562771
     
    29382953    case ArrayWithSlowPutArrayStorage: {
    29392954        // No own property present in the vector, but there might be in the sparse map!
     2955        auto scope = DECLARE_THROW_SCOPE(vm);
    29402956        SparseArrayValueMap* map = arrayStorage()->m_sparseMap.get();
    29412957        bool putResult = false;
    2942         if (!(map && map->contains(i)) && attemptToInterceptPutByIndexOnHole(exec, i, value, shouldThrow, putResult))
    2943             return putResult;
     2958        if (!(map && map->contains(i))) {
     2959            bool result = attemptToInterceptPutByIndexOnHole(exec, i, value, shouldThrow, putResult);
     2960            RETURN_IF_EXCEPTION(scope, false);
     2961            if (result)
     2962                return putResult;
     2963        }
     2964        scope.release();
    29442965        FALLTHROUGH;
    29452966    }
Note: See TracChangeset for help on using the changeset viewer.