mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-09 17:44:56 +09: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.
This commit is contained in:
parent
5d85f3a5c8
commit
962441b3cf
Notes:
github-actions[bot]
2024-12-13 15:10:36 +00:00
Author: https://github.com/trflynn89
Commit: 962441b3cf
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2899
2 changed files with 27 additions and 6 deletions
|
@ -290,12 +290,6 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(VM& vm, TypedArrayB
|
||||||
// 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
|
// 1. Let byteIndexInBuffer be ? ValidateAtomicAccessOnIntegerTypedArray(typedArray, index).
|
||||||
auto byte_index_in_buffer = TRY(validate_atomic_access_on_integer_typed_array(vm, typed_array, 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 expected;
|
||||||
Value replacement;
|
Value replacement;
|
||||||
|
|
||||||
|
@ -319,6 +313,15 @@ static ThrowCompletionOr<Value> atomic_compare_exchange_impl(VM& vm, TypedArrayB
|
||||||
// 6. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
|
// 6. Perform ? RevalidateAtomicAccess(typedArray, byteIndexInBuffer).
|
||||||
TRY(revalidate_atomic_access(vm, typed_array, byte_index_in_buffer));
|
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).
|
// 7. Let elementType be TypedArrayElementType(typedArray).
|
||||||
// 8. Let elementSize be TypedArrayElementSize(typedArray).
|
// 8. Let elementSize be TypedArrayElementSize(typedArray).
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,24 @@ test("error cases", () => {
|
||||||
const array = new Int32Array(4);
|
const array = new Int32Array(4);
|
||||||
Atomics.compareExchange(array, 100, 0, 0);
|
Atomics.compareExchange(array, 100, 0, 0);
|
||||||
}).toThrow(RangeError);
|
}).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)", () => {
|
test("basic functionality (non-BigInt)", () => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue