瀏覽代碼

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

Fixes #9336.
Linus Groh 3 年之前
父節點
當前提交
6fc0b2a43d

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

@@ -4,6 +4,7 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
+#include <AK/Checked.h>
 #include <AK/TypeCasts.h>
 #include <LibJS/Runtime/DataViewPrototype.h>
 
@@ -87,13 +88,19 @@ static Value get_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->get_value<T>(buffer_index, false, ArrayBuffer::Order::Unordered, little_endian);
+    return buffer->get_value<T>(buffer_index.value(), false, ArrayBuffer::Order::Unordered, little_endian);
 }
 
 // 25.3.1.2 SetViewValue ( view, requestIndex, isLittleEndian, type, value ), https://tc39.es/ecma262/#sec-setviewvalue

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

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