Przeglądaj źródła

LibJS: Propagate OOM from GetValueFromBuffer AO

Shannon Booth 2 lat temu
rodzic
commit
3bb15d3dae

+ 3 - 4
Userland/Libraries/LibJS/Runtime/ArrayBuffer.h

@@ -72,7 +72,7 @@ public:
         Unordered
     };
     template<typename type>
-    Value get_value(size_t byte_index, bool is_typed_array, Order, bool is_little_endian = true);
+    ThrowCompletionOr<Value> get_value(size_t byte_index, bool is_typed_array, Order, bool is_little_endian = true);
     template<typename type>
     void set_value(size_t byte_index, Value value, bool is_typed_array, Order, bool is_little_endian = true);
     template<typename T>
@@ -149,7 +149,7 @@ static Value raw_bytes_to_numeric(VM& vm, ByteBuffer raw_value, bool is_little_e
 
 // Implementation for 25.1.2.10 GetValueFromBuffer, used in TypedArray<T>::get_value_from_buffer().
 template<typename T>
-Value ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_array, Order, bool is_little_endian)
+ThrowCompletionOr<Value> ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_array, Order, bool is_little_endian)
 {
     auto& vm = this->vm();
 
@@ -157,8 +157,7 @@ Value ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_a
 
     // FIXME: Check for shared buffer
 
-    // FIXME: Propagate errors.
-    auto raw_value = MUST(buffer_impl().slice(byte_index, element_size));
+    auto raw_value = TRY_OR_THROW_OOM(vm, buffer_impl().slice(byte_index, element_size));
     return raw_bytes_to_numeric<T>(vm, move(raw_value), is_little_endian);
 }
 

+ 1 - 1
Userland/Libraries/LibJS/Runtime/TypedArray.cpp

@@ -189,7 +189,7 @@ static ThrowCompletionOr<void> initialize_typed_array_from_typed_array(VM& vm, T
         // g. Repeat, while count > 0,
         for (u32 i = 0; i < element_length; ++i) {
             // i. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, Unordered).
-            auto value = src_array.get_value_from_buffer(src_byte_index, ArrayBuffer::Order::Unordered);
+            auto value = MUST_OR_THROW_OOM(src_array.get_value_from_buffer(src_byte_index, ArrayBuffer::Order::Unordered));
 
             // ii. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, Unordered).
             data->template set_value<T>(target_byte_index, value, true, ArrayBuffer::Order::Unordered);

+ 4 - 4
Userland/Libraries/LibJS/Runtime/TypedArray.h

@@ -54,7 +54,7 @@ public:
     // 25.1.2.7 IsBigIntElementType ( type ), https://tc39.es/ecma262/#sec-isbigintelementtype
     virtual bool is_bigint_element_type() const = 0;
     // 25.1.2.10 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-getvaluefrombuffer
-    virtual Value get_value_from_buffer(size_t byte_index, ArrayBuffer::Order, bool is_little_endian = true) const = 0;
+    virtual ThrowCompletionOr<Value> get_value_from_buffer(size_t byte_index, ArrayBuffer::Order, bool is_little_endian = true) const = 0;
     // 25.1.2.12 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-setvalueinbuffer
     virtual void set_value_in_buffer(size_t byte_index, Value, ArrayBuffer::Order, bool is_little_endian = true) = 0;
     // 25.1.2.13 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-getmodifysetvalueinbuffer
@@ -100,7 +100,7 @@ inline bool is_valid_integer_index(TypedArrayBase const& typed_array, CanonicalI
 
 // 10.4.5.10 IntegerIndexedElementGet ( O, index ), https://tc39.es/ecma262/#sec-integerindexedelementget
 template<typename T>
-inline Value integer_indexed_element_get(TypedArrayBase const& typed_array, CanonicalIndex property_index)
+inline ThrowCompletionOr<Value> integer_indexed_element_get(TypedArrayBase const& typed_array, CanonicalIndex property_index)
 {
     // 1. If IsValidIntegerIndex(O, index) is false, return undefined.
     if (!is_valid_integer_index(typed_array, property_index))
@@ -195,7 +195,7 @@ public:
             // b. If numericIndex is not undefined, then
             if (!numeric_index.is_undefined()) {
                 // i. Let value be IntegerIndexedElementGet(O, numericIndex).
-                auto value = integer_indexed_element_get<T>(*this, numeric_index);
+                auto value = MUST_OR_THROW_OOM(integer_indexed_element_get<T>(*this, numeric_index));
 
                 // ii. If value is undefined, return undefined.
                 if (value.is_undefined())
@@ -437,7 +437,7 @@ public:
         return is_bigint;
     }
 
-    Value get_value_from_buffer(size_t byte_index, ArrayBuffer::Order order, bool is_little_endian = true) const override { return viewed_array_buffer()->template get_value<T>(byte_index, true, order, is_little_endian); }
+    ThrowCompletionOr<Value> get_value_from_buffer(size_t byte_index, ArrayBuffer::Order order, bool is_little_endian = true) const override { return viewed_array_buffer()->template get_value<T>(byte_index, true, order, is_little_endian); }
     void set_value_in_buffer(size_t byte_index, Value value, ArrayBuffer::Order order, bool is_little_endian = true) override { viewed_array_buffer()->template set_value<T>(byte_index, value, true, order, is_little_endian); }
     ThrowCompletionOr<Value> get_modify_set_value_in_buffer(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true) override { return viewed_array_buffer()->template get_modify_set_value<T>(byte_index, value, move(operation), is_little_endian); }
 

+ 3 - 3
Userland/Libraries/LibJS/Runtime/TypedArrayPrototype.cpp

@@ -415,7 +415,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::copy_within)
         // k. Repeat, while countBytes > 0,
         for (; count_bytes > 0; --count_bytes) {
             // i. Let value be GetValueFromBuffer(buffer, fromByteIndex, Uint8, true, Unordered).
-            auto value = buffer->get_value<u8>(from_byte_index, true, ArrayBuffer::Order::Unordered);
+            auto value = MUST_OR_THROW_OOM(buffer->get_value<u8>(from_byte_index, true, ArrayBuffer::Order::Unordered));
 
             // ii. Perform SetValueInBuffer(buffer, toByteIndex, Uint8, value, true, Unordered).
             buffer->set_value<u8>(to_byte_index, value, true, ArrayBuffer::Order::Unordered);
@@ -1231,7 +1231,7 @@ static ThrowCompletionOr<void> set_typed_array_from_typed_array(VM& vm, TypedArr
         // a. Repeat, while targetByteIndex < limit,
         while (target_byte_index < limit) {
             // i. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, srcType, true, Unordered).
-            auto value = source.get_value_from_buffer(source_byte_index, ArrayBuffer::Unordered);
+            auto value = MUST_OR_THROW_OOM(source.get_value_from_buffer(source_byte_index, ArrayBuffer::Unordered));
             // ii. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, value, true, Unordered).
             target.set_value_in_buffer(target_byte_index, value, ArrayBuffer::Unordered);
             // iii. Set srcByteIndex to srcByteIndex + srcElementSize.
@@ -1459,7 +1459,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::slice)
             // ix. Repeat, while targetByteIndex < limit,
             for (; target_byte_index < limit.value(); ++source_byte_index, ++target_byte_index) {
                 // 1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, Uint8, true, Unordered).
-                auto value = source_buffer.get_value<u8>(source_byte_index.value(), true, ArrayBuffer::Unordered);
+                auto value = MUST_OR_THROW_OOM(source_buffer.get_value<u8>(source_byte_index.value(), true, ArrayBuffer::Unordered));
 
                 // 2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, Uint8, value, true, Unordered).
                 target_buffer.set_value<u8>(target_byte_index, value, true, ArrayBuffer::Unordered);

+ 1 - 1
Userland/Libraries/LibWeb/WebIDL/AbstractOperations.cpp

@@ -74,7 +74,7 @@ ErrorOr<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source)
 
     // 9. For i in the range offset to offset + length − 1, inclusive, set bytes[i − offset] to ! GetValueFromBuffer(esArrayBuffer, i, Uint8, true, Unordered).
     for (u64 i = offset; i < offset + length; ++i) {
-        auto value = es_array_buffer->get_value<u8>(i, true, JS::ArrayBuffer::Unordered);
+        auto value = es_array_buffer->get_value<u8>(i, true, JS::ArrayBuffer::Unordered).release_allocated_value_but_fixme_should_propagate_errors();
         bytes[i - offset] = static_cast<u8>(value.as_double());
     }