Explorar o código

LibJS: Use Checked<T> for offsets in the SetViewValue AO

Fixes #9338.
Linus Groh %!s(int64=4) %!d(string=hai) anos
pai
achega
84053816d5

+ 9 - 3
Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp

@@ -136,13 +136,19 @@ static Value set_view_value(GlobalObject& global_object, Value request_index, Va
     auto view_size = view->byte_length();
 
     auto element_size = sizeof(T);
-    if (get_index + element_size > view_size) {
+
+    Checked<size_t> buffer_index = get_index;
+    buffer_index += view_offset;
+
+    Checked<size_t> end_index = get_index;
+    end_index += element_size;
+
+    if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size) {
         vm.throw_exception<RangeError>(global_object, ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
         return {};
     }
 
-    auto buffer_index = get_index + view_offset;
-    return buffer->set_value<T>(buffer_index, number_value, false, ArrayBuffer::Order::Unordered, little_endian);
+    return buffer->set_value<T>(buffer_index.value(), number_value, false, ArrayBuffer::Order::Unordered, little_endian);
 }
 
 // 25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getbigint64

+ 20 - 0
Userland/Libraries/LibJS/Tests/builtins/DataView/DataView-invalid-read-and-write.js

@@ -7,3 +7,23 @@ test("Issue #9336, integer overflow in get_view_value", () => {
         "Data view byte offset 4294967292 is out of range for buffer with length 16"
     );
 });
+
+test("Issue #9338, integer overflow in set_view_value", () => {
+    const dataView = new DataView(new ArrayBuffer(16));
+    expect(() => {
+        dataView.setUint32(0xfffffffc, 0);
+    }).toThrowWithMessage(
+        RangeError,
+        "Data view byte offset 4294967292 is out of range for buffer with length 16"
+    );
+});
+
+test("Issue #9338, integer overflow in set_view_value - zero-length DataView", () => {
+    const dataView = new DataView(new ArrayBuffer(4), 4);
+    expect(() => {
+        dataView.setUint32(0xfffffffc, 0);
+    }).toThrowWithMessage(
+        RangeError,
+        "Data view byte offset 4294967292 is out of range for buffer with length 0"
+    );
+});