Changeset 214684 in webkit


Ignore:
Timestamp:
Mar 31, 2017 1:18:05 PM (7 years ago)
Author:
mark.lam@apple.com
Message:

Array.prototype.splice() should not be using JSArray::tryCreateForInitializationPrivate().
https://bugs.webkit.org/show_bug.cgi?id=170303
<rdar://problem/31358281>

Reviewed by Filip Pizlo.

This is because it needs to call getProperty() later to get the values for
initializing the array. getProperty() can execute arbitrary code and potentially
trigger the GC. This is not allowed for clients of JSArray::tryCreateForInitializationPrivate().

  • runtime/ArrayPrototype.cpp:

(JSC::arrayProtoFuncSplice):
(JSC::copySplicedArrayElements): Deleted.

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r214662 r214684  
     12017-03-31  Mark Lam  <mark.lam@apple.com>
     2
     3        Array.prototype.splice() should not be using JSArray::tryCreateForInitializationPrivate().
     4        https://bugs.webkit.org/show_bug.cgi?id=170303
     5        <rdar://problem/31358281>
     6
     7        Reviewed by Filip Pizlo.
     8
     9        This is because it needs to call getProperty() later to get the values for
     10        initializing the array.  getProperty() can execute arbitrary code and potentially
     11        trigger the GC.  This is not allowed for clients of JSArray::tryCreateForInitializationPrivate().
     12
     13        * runtime/ArrayPrototype.cpp:
     14        (JSC::arrayProtoFuncSplice):
     15        (JSC::copySplicedArrayElements): Deleted.
     16
    1172017-03-31  Oleksandr Skachkov  <gskachkov@gmail.com>
    218
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r214374 r214684  
    968968}
    969969
    970 template<bool needToFillHolesManually>
    971 inline bool copySplicedArrayElements(ExecState* exec, ThrowScope& scope, JSObject* result, JSObject* thisObj, unsigned actualStart, unsigned actualDeleteCount)
    972 {
    973     VM& vm = scope.vm();
    974     for (unsigned k = 0; k < actualDeleteCount; ++k) {
    975         JSValue v = getProperty(exec, thisObj, k + actualStart);
    976         RETURN_IF_EXCEPTION(scope, false);
    977         if (UNLIKELY(!v && !needToFillHolesManually))
    978             continue;
    979         result->initializeIndex(vm, k, v);
    980     }
    981     return true;
    982 }
    983 
    984970EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
    985971{
     
    10561042            }
    10571043        } else {
    1058             result = JSArray::tryCreateForInitializationPrivate(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), actualDeleteCount);
     1044            result = JSArray::tryCreate(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), actualDeleteCount);
    10591045            if (UNLIKELY(!result)) {
    10601046                throwOutOfMemoryError(exec, scope);
     
    10621048            }
    10631049
    1064             // The result can have an ArrayStorage indexing type if we're having a bad time.
    1065             bool isArrayStorage = hasAnyArrayStorage(result->indexingType());
    1066             bool success = false;
    1067             if (UNLIKELY(isArrayStorage)) {
    1068                 static const bool needToFillHolesManually = true;
    1069                 success = copySplicedArrayElements<needToFillHolesManually>(exec, scope, result, thisObj, actualStart, actualDeleteCount);
    1070             } else {
    1071                 ASSERT(hasUndecided(result->indexingType()));
    1072                 static const bool needToFillHolesManually = false;
    1073                 success = copySplicedArrayElements<needToFillHolesManually>(exec, scope, result, thisObj, actualStart, actualDeleteCount);
    1074             }
    1075             if (UNLIKELY(!success)) {
    1076                 ASSERT(scope.exception());
    1077                 return encodedJSValue();
     1050            for (unsigned k = 0; k < actualDeleteCount; ++k) {
     1051                JSValue v = getProperty(exec, thisObj, k + actualStart);
     1052                RETURN_IF_EXCEPTION(scope, encodedJSValue());
     1053                if (UNLIKELY(!v))
     1054                    continue;
     1055                result->putDirectIndex(exec, k, v);
     1056                RETURN_IF_EXCEPTION(scope, encodedJSValue());
    10781057            }
    10791058        }
Note: See TracChangeset for help on using the changeset viewer.