From 7589cc2494c396f580f9f0c4db92a3623d9749c3 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Sun, 5 Sep 2021 14:43:15 +0430 Subject: LibJS: Handle possible allocation failure in ArrayBuffer(size_t) ...by replacing it with a ctor that takes the buffer instead, and handling the allocation failure in ArrayBuffer::create(size_t) by throwing a RangeError as specified by the spec. --- Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp | 11 ++++++++--- Userland/Libraries/LibJS/Runtime/ArrayBuffer.h | 2 +- Userland/Libraries/LibJS/Runtime/ArrayBufferConstructor.cpp | 6 +++++- Userland/Libraries/LibJS/Runtime/ErrorTypes.h | 3 ++- Userland/Libraries/LibJS/Runtime/TypedArray.cpp | 6 ++++++ 5 files changed, 22 insertions(+), 6 deletions(-) (limited to 'Userland/Libraries/LibJS/Runtime') diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp index 3a0b543fce..c92bc590e4 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.cpp @@ -11,7 +11,12 @@ namespace JS { ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, size_t byte_size) { - return global_object.heap().allocate(global_object, byte_size, *global_object.array_buffer_prototype()); + auto buffer = ByteBuffer::create_zeroed(byte_size); + if (!buffer.has_value()) { + global_object.vm().throw_exception(global_object, ErrorType::NotEnoughMemoryToAllocate, byte_size); + return nullptr; + } + return global_object.heap().allocate(global_object, buffer.release_value(), *global_object.array_buffer_prototype()); } ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer* buffer) @@ -19,9 +24,9 @@ ArrayBuffer* ArrayBuffer::create(GlobalObject& global_object, ByteBuffer* buffer return global_object.heap().allocate(global_object, buffer, *global_object.array_buffer_prototype()); } -ArrayBuffer::ArrayBuffer(size_t byte_size, Object& prototype) +ArrayBuffer::ArrayBuffer(ByteBuffer buffer, Object& prototype) : Object(prototype) - , m_buffer(ByteBuffer::create_zeroed(byte_size).release_value()) // FIXME: Handle this possible OOM failure. + , m_buffer(move(buffer)) , m_detach_key(js_undefined()) { } diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h index 5868ef29cb..2242a1644a 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h +++ b/Userland/Libraries/LibJS/Runtime/ArrayBuffer.h @@ -27,7 +27,7 @@ public: static ArrayBuffer* create(GlobalObject&, size_t); static ArrayBuffer* create(GlobalObject&, ByteBuffer*); - ArrayBuffer(size_t, Object& prototype); + ArrayBuffer(ByteBuffer buffer, Object& prototype); ArrayBuffer(ByteBuffer* buffer, Object& prototype); virtual ~ArrayBuffer() override; diff --git a/Userland/Libraries/LibJS/Runtime/ArrayBufferConstructor.cpp b/Userland/Libraries/LibJS/Runtime/ArrayBufferConstructor.cpp index 6a18c40e6e..c140108a95 100644 --- a/Userland/Libraries/LibJS/Runtime/ArrayBufferConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/ArrayBufferConstructor.cpp @@ -60,7 +60,11 @@ Value ArrayBufferConstructor::construct(FunctionObject&) } return {}; } - return ArrayBuffer::create(global_object(), byte_length); + auto array_buffer = ArrayBuffer::create(global_object(), byte_length); + if (!array_buffer) + return {}; + + return array_buffer; } // 25.1.4.1 ArrayBuffer.isView ( arg ), https://tc39.es/ecma262/#sec-arraybuffer.isview diff --git a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h index 1ed7e8da73..b2098d431a 100644 --- a/Userland/Libraries/LibJS/Runtime/ErrorTypes.h +++ b/Userland/Libraries/LibJS/Runtime/ErrorTypes.h @@ -213,7 +213,8 @@ M(BadArgCountOne, "{}() needs one argument") \ M(BadArgCountAtLeastOne, "{}() needs at least one argument") \ M(BadArgCountMany, "{}() needs {} arguments") \ - M(FixmeAddAnErrorString, "FIXME: Add a string for this error.") + M(FixmeAddAnErrorString, "FIXME: Add a string for this error.") \ + M(NotEnoughMemoryToAllocate, "Not enough memory to allocate {} bytes") namespace JS { diff --git a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp index 4fa99ab3bb..0cac033ff6 100644 --- a/Userland/Libraries/LibJS/Runtime/TypedArray.cpp +++ b/Userland/Libraries/LibJS/Runtime/TypedArray.cpp @@ -182,6 +182,9 @@ static void initialize_typed_array_from_array_like(GlobalObject& global_object, } auto byte_length = element_size * length; auto array_buffer = ArrayBuffer::create(global_object, byte_length); + if (!array_buffer) + return; + typed_array.set_viewed_array_buffer(array_buffer); typed_array.set_byte_length(byte_length); typed_array.set_byte_offset(0); @@ -215,6 +218,9 @@ static void initialize_typed_array_from_list(GlobalObject& global_object, TypedA } auto byte_length = element_size * list.size(); auto array_buffer = ArrayBuffer::create(global_object, byte_length); + if (!array_buffer) + return; + typed_array.set_viewed_array_buffer(array_buffer); typed_array.set_byte_length(byte_length); typed_array.set_byte_offset(0); -- cgit v1.2.3