Changeset 266257 in webkit for trunk/Source/JavaScriptCore


Ignore:
Timestamp:
Aug 27, 2020, 2:32:55 PM (5 years ago)
Author:
[email protected]
Message:

[JSC] setLength in Array#push could get very large length
https://bugs.webkit.org/show_bug.cgi?id=215897
<rdar://problem/67859149>

Reviewed by Keith Miller.

JSTests:

  • stress/array-push-more-than-max-size.js: Added.

(shouldBe):
(shouldThrow):

Source/JavaScriptCore:

Array#push can get length larger than UINT32_MAX. And in this case, we should throw a RangeError.
Before r266215, it was using putLength which throws an error. But it was replaced with setLength,
and JSC::setLength assumes that it never gets a length greater than UINT32_MAX by asserting. We
should fix it so that Array#push should thrown an error correctly.

  • runtime/ArrayPrototype.cpp:

(JSC::setLength):

Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r266254 r266257  
     12020-08-27  Yusuke Suzuki  <[email protected]>
     2
     3        [JSC] setLength in Array#push could get very large length
     4        https://bugs.webkit.org/show_bug.cgi?id=215897
     5        <rdar://problem/67859149>
     6
     7        Reviewed by Keith Miller.
     8
     9        Array#push can get length larger than UINT32_MAX. And in this case, we should throw a RangeError.
     10        Before r266215, it was using putLength which throws an error. But it was replaced with setLength,
     11        and JSC::setLength assumes that it never gets a length greater than UINT32_MAX by asserting. We
     12        should fix it so that Array#push should thrown an error correctly.
     13
     14        * runtime/ArrayPrototype.cpp:
     15        (JSC::setLength):
     16
    1172020-08-27  Saam Barati  <[email protected]>
    218
  • trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp

    r266215 r266257  
    163163static ALWAYS_INLINE void setLength(JSGlobalObject* globalObject, VM& vm, JSObject* obj, uint64_t value)
    164164{
     165    auto scope = DECLARE_THROW_SCOPE(vm);
    165166    static constexpr bool throwException = true;
    166167    if (LIKELY(isJSArray(obj))) {
    167         ASSERT(static_cast<uint32_t>(value) == value);
     168        if (UNLIKELY(value > UINT32_MAX)) {
     169            throwRangeError(globalObject, scope, "Invalid array length"_s);
     170            return;
     171        }
     172        scope.release();
    168173        jsCast<JSArray*>(obj)->setLength(globalObject, static_cast<uint32_t>(value), throwException);
    169     } else {
    170         PutPropertySlot slot(obj, throwException);
    171         obj->methodTable(vm)->put(obj, globalObject, vm.propertyNames->length, jsNumber(value), slot);
    172     }
     174        return;
     175    }
     176    scope.release();
     177    PutPropertySlot slot(obj, throwException);
     178    obj->methodTable(vm)->put(obj, globalObject, vm.propertyNames->length, jsNumber(value), slot);
    173179}
    174180
Note: See TracChangeset for help on using the changeset viewer.