mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
LibJS: Avoid internal assertion accessing detached TA internal slots
This defers accessing TA internal slots until we know we have a valid, attached TA. Our implementation has assertions that guard against this. (cherry picked from commit 962441b3cf34c1350877ac7c73351657c10f675b)
This commit is contained in:
1 parent
6fcbd25d0d
commit
62ced93997
2 files changed
+27
-6
No files matched your search
@@ -289,12 +289,6 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(VM& vm, TypedArrayB
|
||||
// 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
|
||||
auto byte_index_in_buffer = TRY(validate_atomic_access_on_integer_typed_array(vm, typed_array, index));
|
||||
|
||||
// 2. Let buffer be typedArray.[[ViewedArrayBuffer]].
|
||||
auto* buffer = typed_array.viewed_array_buffer();
|
||||
|
||||
// 3. Let block be buffer.[[ArrayBufferData]].
|
||||
auto& block = buffer->buffer();
|
||||
|
||||
Value expected;
|
||||
Value replacement;
|
||||
|
||||
@@ -318,6 +312,15 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(VM& vm, TypedArrayB
|
||||
// 6. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
|
||||
TRY(revalidate_atomic_access(vm, typed_array, byte_index_in_buffer));
|
||||
|
||||
// NOTE: We defer steps 2 and 3 to ensure we have revalidated the TA before accessing these internal slots.
|
||||
// In our implementation, accessing [[ArrayBufferData]] on a detached buffer will fail assertions.
|
||||
|
||||
// 2. Let buffer be typedArray.[[ViewedArrayBuffer]].
|
||||
auto* buffer = typed_array.viewed_array_buffer();
|
||||
|
||||
// 3. Let block be buffer.[[ArrayBufferData]].
|
||||
auto& block = buffer->buffer();
|
||||
|
||||
// 7. Let elementType be TypedArrayElementType(typedArray).
|
||||
// 8. Let elementSize be TypedArrayElementSize(typedArray).
|
||||
|
||||
|
||||
@@ -21,6 +21,24 @@ test("error cases", () => {
|
||||
const array = new Int32Array(4);
|
||||
Atomics.compareExchange(array, 100, 0, 0);
|
||||
}).toThrow(RangeError);
|
||||
|
||||
expect(() => {
|
||||
const array = new Int32Array(4);
|
||||
|
||||
function detachArrayWhileAccessingIndex(array) {
|
||||
return {
|
||||
valueOf() {
|
||||
detachArrayBuffer(array.buffer);
|
||||
return 0;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Atomics.compareExchange(array, detachArrayWhileAccessingIndex(array), 0, 0);
|
||||
}).toThrowWithMessage(
|
||||
TypeError,
|
||||
"TypedArray contains a property which references a value at an index not contained within its buffer's bounds"
|
||||
);
|
||||
});
|
||||
|
||||
test("basic functionality (non-BigInt)", () => {
|
||||
|
||||
Reference in new issue
Block a user