summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Runtime
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2023-05-25 11:22:01 -0400
committerAndreas Kling <kling@serenityos.org>2023-05-26 05:23:55 +0200
commit706a20c4d4acbfc9eb9d980969f29e4b1c7a4d1c (patch)
tree67e2af777ce40355f14fc6dd8369f6901b4915bd /Userland/Libraries/LibJS/Runtime
parentd31b780760662b9099909316e4901eae9da758f7 (diff)
downloadserenity-706a20c4d4acbfc9eb9d980969f29e4b1c7a4d1c.zip
LibJS: Disallow creating ArrayBuffers larger than 2^53 - 1
This is a normative change in the ECMA-262 spec. See: https://github.com/tc39/ecma262/commit/25f9744
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime')
-rw-r--r--Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp23
1 files changed, 19 insertions, 4 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp
index 843eefb428..942881df6a 100644
--- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp
+++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp
@@ -50,6 +50,23 @@ void ArrayBuffer::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_detach_key);
}
+// 6.2.9.1 CreateByteDataBlock ( size ), https://tc39.es/ecma262/#sec-createbytedatablock
+static ThrowCompletionOr<ByteBuffer> create_byte_data_block(VM& vm, size_t size)
+{
+ // 1. If size > 2^53 - 1, throw a RangeError exception.
+ if (size > MAX_ARRAY_LIKE_INDEX)
+ return vm.throw_completion<RangeError>(ErrorType::InvalidLength, "array buffer");
+
+ // 2. Let db be a new Data Block value consisting of size bytes. If it is impossible to create such a Data Block, throw a RangeError exception.
+ // 3. Set all of the bytes of db to 0.
+ auto data_block = ByteBuffer::create_zeroed(size);
+ if (data_block.is_error())
+ return vm.throw_completion<RangeError>(ErrorType::NotEnoughMemoryToAllocate, size);
+
+ // 4. Return db.
+ return data_block.release_value();
+}
+
// 25.1.2.1 AllocateArrayBuffer ( constructor, byteLength ), https://tc39.es/ecma262/#sec-allocatearraybuffer
ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(VM& vm, FunctionObject& constructor, size_t byte_length)
{
@@ -57,12 +74,10 @@ ThrowCompletionOr<ArrayBuffer*> allocate_array_buffer(VM& vm, FunctionObject& co
auto obj = TRY(ordinary_create_from_constructor<ArrayBuffer>(vm, constructor, &Intrinsics::array_buffer_prototype, nullptr));
// 2. Let block be ? CreateByteDataBlock(byteLength).
- auto block = ByteBuffer::create_zeroed(byte_length);
- if (block.is_error())
- return vm.throw_completion<RangeError>(ErrorType::NotEnoughMemoryToAllocate, byte_length);
+ auto block = TRY(create_byte_data_block(vm, byte_length));
// 3. Set obj.[[ArrayBufferData]] to block.
- obj->set_buffer(block.release_value());
+ obj->set_buffer(move(block));
// 4. Set obj.[[ArrayBufferByteLength]] to byteLength.