Skip to content

Commit

Permalink
Cherry-pick 259548.785@safari-7615-branch (f2a2820). https://bugs.web…
Browse files Browse the repository at this point in the history
…kit.org/show_bug.cgi?id=257387

    [JSC] Recompute length properly when resize happens during TypedArray#copyWithin
    https://bugs.webkit.org/show_bug.cgi?id=257387
    rdar://109851495

    Reviewed by Mark Lam.

    copyWithin's side effectful operation can resize resizable ArrayBuffer. We have a code catching this and recompute the appropriate copy count
    again, but it can overflow if `to` or `from` are larger than the newly updated `length`. This patch handles this case correctly: returning
    since there is no copying content in this case.

    * JSTests/stress/resizable-array-buffer-copy-within-length-update.js: Added.
    (call_back):
    * Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
    (JSC::genericTypedArrayViewProtoFuncCopyWithin):

    Canonical link: https://commits.webkit.org/259548.785@safari-7615-branch
  • Loading branch information
Constellation authored and mcatanzaro committed Jul 28, 2023
1 parent 920a619 commit 5898307
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const ab = new ArrayBuffer(0x1000, {"maxByteLength": 0x4000});
const u8 = new Uint8Array(ab);
function call_back() {
ab.resize(0);
return 0;
}
u8.copyWithin(0x20, {valueOf:call_back});
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,12 @@ ALWAYS_INLINE EncodedJSValue genericTypedArrayViewProtoFuncCopyWithin(VM& vm, JS
// https://tc39.es/proposal-resizablearraybuffer/#sec-%typedarray%.prototype.copywithin
if (updatedLength.value() != length) {
length = updatedLength.value();
if (std::max(to, from) + count > length)
if (std::max(to, from) + count > length) {
// Either to or from index is larger than the updated length. In this case, we do not need to copy anything and finish copyWithin.
if (std::max(to, from) > length)
return JSValue::encode(callFrame->thisValue());
count = length - std::max(to, from);
}
}

typename ViewClass::ElementType* array = thisObject->typedVector();
Expand Down

0 comments on commit 5898307

Please sign in to comment.