Title: [171323] trunk
Revision
171323
Author
[email protected]
Date
2014-07-21 17:26:19 -0700 (Mon, 21 Jul 2014)

Log Message

new Int32Array(new ArrayBuffer(100), 1, 1) shouldn't throw an error that says "RangeError: Byte offset and length out of range of buffer"
https://bugs.webkit.org/show_bug.cgi?id=125391

Patch by Diego Pino Garcia <[email protected]> on 2014-07-21
Reviewed by Darin Adler.

Source/_javascript_Core:
Create own method for verifying byte offset alignment.

* runtime/ArrayBufferView.h:
(JSC::ArrayBufferView::verifyByteOffsetAlignment):
(JSC::ArrayBufferView::verifySubRangeLength):
(JSC::ArrayBufferView::verifySubRange): Deleted.
* runtime/GenericTypedArrayViewInlines.h:
(JSC::GenericTypedArrayView<Adaptor>::create):
* runtime/JSDataView.cpp:
(JSC::JSDataView::create):
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::create):

LayoutTests:
* fast/canvas/webgl/data-view-crash-expected.txt:
* fast/canvas/webgl/data-view-test-expected.txt:
* fast/canvas/webgl/data-view-test.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (171322 => 171323)


--- trunk/LayoutTests/ChangeLog	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/LayoutTests/ChangeLog	2014-07-22 00:26:19 UTC (rev 171323)
@@ -1,3 +1,14 @@
+2014-07-21  Diego Pino Garcia  <[email protected]>
+
+        new Int32Array(new ArrayBuffer(100), 1, 1) shouldn't throw an error that says "RangeError: Byte offset and length out of range of buffer"
+        https://bugs.webkit.org/show_bug.cgi?id=125391
+
+        Reviewed by Darin Adler.
+
+        * fast/canvas/webgl/data-view-crash-expected.txt:
+        * fast/canvas/webgl/data-view-test-expected.txt:
+        * fast/canvas/webgl/data-view-test.html:
+
 2014-07-21  Alexey Proskuryakov  <[email protected]>
 
         REGRESSION: fast/layers/no-clipping-overflow-hidden-added-after-transform.html is flaky

Modified: trunk/LayoutTests/fast/canvas/webgl/data-view-crash-expected.txt (171322 => 171323)


--- trunk/LayoutTests/fast/canvas/webgl/data-view-crash-expected.txt	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/LayoutTests/fast/canvas/webgl/data-view-crash-expected.txt	2014-07-22 00:26:19 UTC (rev 171323)
@@ -2,8 +2,8 @@
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
-PASS view = new DataView(array.buffer, -4500000000) threw exception RangeError: Byte offset and length out of range of buffer.
-PASS view = new DataView(array.buffer, -4500000000, 4500000000) threw exception RangeError: Byte offset and length out of range of buffer.
+PASS view = new DataView(array.buffer, -4500000000) threw exception RangeError: Length out of range of buffer.
+PASS view = new DataView(array.buffer, -4500000000, 4500000000) threw exception RangeError: Length out of range of buffer.
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/canvas/webgl/data-view-test-expected.txt (171322 => 171323)


--- trunk/LayoutTests/fast/canvas/webgl/data-view-test-expected.txt	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/LayoutTests/fast/canvas/webgl/data-view-test-expected.txt	2014-07-22 00:26:19 UTC (rev 171323)
@@ -7,25 +7,31 @@
 PASS DataView(new ArrayBuffer) threw exception
 
 Test for constructor taking 1 argument
-PASS view = new DataView(arayBuffer) is defined.
+PASS view = new DataView(arrayBuffer) is defined.
 PASS view.byteOffset is 0
 PASS view.byteLength is 2
 
 Test for constructor taking 2 arguments
-PASS view = new DataView(arayBuffer, 1) is defined.
+PASS view = new DataView(arrayBuffer, 1) is defined.
 PASS view.byteOffset is 1
 PASS view.byteLength is 1
 
 Test for constructor taking 3 arguments
-PASS view = new DataView(arayBuffer, 0, 1) is defined.
+PASS view = new DataView(arrayBuffer, 0, 1) is defined.
 PASS view.byteOffset is 0
 PASS view.byteLength is 1
 
 Test for constructor throwing exception
-PASS view = new DataView(arayBuffer, 0, 3) threw exception RangeError: Byte offset and length out of range of buffer.
-PASS view = new DataView(arayBuffer, 1, 2) threw exception RangeError: Byte offset and length out of range of buffer.
-PASS view = new DataView(arayBuffer, 2, 1) threw exception RangeError: Byte offset and length out of range of buffer.
+PASS view = new DataView(arrayBuffer, 0, 3) threw exception RangeError: Length out of range of buffer.
+PASS view = new DataView(arrayBuffer, 1, 2) threw exception RangeError: Length out of range of buffer.
+PASS view = new DataView(arrayBuffer, 2, 1) threw exception RangeError: Length out of range of buffer.
 
+Test for constructor throwing wrong byteoffset exception
+PASS view = new Int32Array(new ArrayBuffer(100), 1, 1) threw exception RangeError: Byte offset is not aligned.
+
+Test for constructor wrong length exception takes precedence over wrong byteoffset exception
+PASS view = new Int32Array(new ArrayBuffer(100), 1, 101) threw exception RangeError: Length out of range of buffer.
+
 Test for get methods that work
 PASS view.getInt8(0) is 0
 PASS view.getInt8(8) is -128

Modified: trunk/LayoutTests/fast/canvas/webgl/data-view-test.html (171322 => 171323)


--- trunk/LayoutTests/fast/canvas/webgl/data-view-test.html	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/LayoutTests/fast/canvas/webgl/data-view-test.html	2014-07-22 00:26:19 UTC (rev 171323)
@@ -230,7 +230,7 @@
 
 function runConstructorTests()
 {
-    arayBuffer = (new Uint8Array([1, 2])).buffer;
+    arrayBuffer = (new Uint8Array([1, 2])).buffer;
 
     debug("");
     debug("Test for constructor not called as a function");
@@ -245,27 +245,35 @@
 
     debug("");
     debug("Test for constructor taking 1 argument");
-    shouldBeDefined("view = new DataView(arayBuffer)");
+    shouldBeDefined("view = new DataView(arrayBuffer)");
     shouldBe("view.byteOffset", "0");
     shouldBe("view.byteLength", "2");
 
     debug("");
     debug("Test for constructor taking 2 arguments");
-    shouldBeDefined("view = new DataView(arayBuffer, 1)");
+    shouldBeDefined("view = new DataView(arrayBuffer, 1)");
     shouldBe("view.byteOffset", "1");
     shouldBe("view.byteLength", "1");
 
     debug("");
     debug("Test for constructor taking 3 arguments");
-    shouldBeDefined("view = new DataView(arayBuffer, 0, 1)");
+    shouldBeDefined("view = new DataView(arrayBuffer, 0, 1)");
     shouldBe("view.byteOffset", "0");
     shouldBe("view.byteLength", "1");
 
     debug("");
     debug("Test for constructor throwing exception");
-    shouldThrow("view = new DataView(arayBuffer, 0, 3)");
-    shouldThrow("view = new DataView(arayBuffer, 1, 2)");
-    shouldThrow("view = new DataView(arayBuffer, 2, 1)");
+    shouldThrow("view = new DataView(arrayBuffer, 0, 3)");
+    shouldThrow("view = new DataView(arrayBuffer, 1, 2)");
+    shouldThrow("view = new DataView(arrayBuffer, 2, 1)");
+
+    debug("");
+    debug("Test for constructor throwing wrong byteoffset exception");
+    shouldThrow("view = new Int32Array(new ArrayBuffer(100), 1, 1)");
+
+    debug("");
+    debug("Test for constructor wrong length exception takes precedence over wrong byteoffset exception");
+    shouldThrow("view = new Int32Array(new ArrayBuffer(100), 1, 101)");
 }
 
 function runGetTests()

Modified: trunk/Source/_javascript_Core/ChangeLog (171322 => 171323)


--- trunk/Source/_javascript_Core/ChangeLog	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-07-22 00:26:19 UTC (rev 171323)
@@ -1,3 +1,23 @@
+2014-07-21  Diego Pino Garcia  <[email protected]>
+
+        new Int32Array(new ArrayBuffer(100), 1, 1) shouldn't throw an error that says "RangeError: Byte offset and length out of range of buffer"
+        https://bugs.webkit.org/show_bug.cgi?id=125391
+
+        Reviewed by Darin Adler.
+
+        Create own method for verifying byte offset alignment.
+
+        * runtime/ArrayBufferView.h:
+        (JSC::ArrayBufferView::verifyByteOffsetAlignment):
+        (JSC::ArrayBufferView::verifySubRangeLength):
+        (JSC::ArrayBufferView::verifySubRange): Deleted.
+        * runtime/GenericTypedArrayViewInlines.h:
+        (JSC::GenericTypedArrayView<Adaptor>::create):
+        * runtime/JSDataView.cpp:
+        (JSC::JSDataView::create):
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::create):
+
 2014-07-20  Diego Pino Garcia  <[email protected]>
 
         ES6: Implement Math.sign()

Modified: trunk/Source/_javascript_Core/runtime/ArrayBufferView.h (171322 => 171323)


--- trunk/Source/_javascript_Core/runtime/ArrayBufferView.h	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/Source/_javascript_Core/runtime/ArrayBufferView.h	2014-07-22 00:26:19 UTC (rev 171323)
@@ -77,22 +77,20 @@
 
     JS_EXPORT_PRIVATE virtual ~ArrayBufferView();
 
+    // Helper to verify byte offset is size aligned.
+    static bool verifyByteOffsetAlignment(unsigned byteOffset, size_t size)
+    {
+        return !(byteOffset & (size - 1));
+    }
+
     // Helper to verify that a given sub-range of an ArrayBuffer is
     // within range.
-    // FIXME: This should distinguish between alignment errors and bounds errors.
-    // https://bugs.webkit.org/show_bug.cgi?id=125391
-    template <typename T>
-    static bool verifySubRange(
-        PassRefPtr<ArrayBuffer> buffer,
-        unsigned byteOffset,
-        unsigned numElements)
+    static bool verifySubRangeLength(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned numElements, size_t size)
     {
         unsigned byteLength = buffer->byteLength();
-        if (sizeof(T) > 1 && byteOffset % sizeof(T))
-            return false;
         if (byteOffset > byteLength)
             return false;
-        unsigned remainingElements = (byteLength - byteOffset) / sizeof(T);
+        unsigned remainingElements = (byteLength - byteOffset) / size;
         if (numElements > remainingElements)
             return false;
         return true;

Modified: trunk/Source/_javascript_Core/runtime/GenericTypedArrayViewInlines.h (171322 => 171323)


--- trunk/Source/_javascript_Core/runtime/GenericTypedArrayViewInlines.h	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/Source/_javascript_Core/runtime/GenericTypedArrayViewInlines.h	2014-07-22 00:26:19 UTC (rev 171323)
@@ -62,8 +62,10 @@
     PassRefPtr<ArrayBuffer> passedBuffer, unsigned byteOffset, unsigned length)
 {
     RefPtr<ArrayBuffer> buffer = passedBuffer;
-    if (!verifySubRange<typename Adaptor::Type>(buffer, byteOffset, length))
-        return 0;
+    if (!verifySubRangeLength(buffer, byteOffset, length, sizeof(typename Adaptor::Type))
+        || !verifyByteOffsetAlignment(byteOffset, sizeof(typename Adaptor::Type))) {
+        return nullptr;
+    }
     
     return adoptRef(new GenericTypedArrayView(buffer, byteOffset, length));
 }

Modified: trunk/Source/_javascript_Core/runtime/JSDataView.cpp (171322 => 171323)


--- trunk/Source/_javascript_Core/runtime/JSDataView.cpp	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/Source/_javascript_Core/runtime/JSDataView.cpp	2014-07-22 00:26:19 UTC (rev 171323)
@@ -47,11 +47,14 @@
     unsigned byteOffset, unsigned byteLength)
 {
     RefPtr<ArrayBuffer> buffer = passedBuffer;
-    if (!ArrayBufferView::verifySubRange<uint8_t>(buffer, byteOffset, byteLength)) {
-        throwVMError(
-            exec, createRangeError(exec, "Byte offset and length out of range of buffer"));
-        return 0;
+    if (!ArrayBufferView::verifySubRangeLength(buffer, byteOffset, byteLength, sizeof(uint8_t))) {
+        throwVMError(exec, createRangeError(exec, "Length out of range of buffer"));
+        return nullptr;
     }
+    if (!ArrayBufferView::verifyByteOffsetAlignment(byteOffset, sizeof(uint8_t))) {
+        exec->vm().throwException(exec, createRangeError(exec, "Byte offset is not aligned"));
+        return nullptr;
+    }
     VM& vm = exec->vm();
     ConstructionContext context(
         structure, buffer, byteOffset, byteLength, ConstructionContext::DataView);

Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h (171322 => 171323)


--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h	2014-07-22 00:10:11 UTC (rev 171322)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewInlines.h	2014-07-22 00:26:19 UTC (rev 171323)
@@ -83,11 +83,15 @@
     unsigned byteOffset, unsigned length)
 {
     RefPtr<ArrayBuffer> buffer = passedBuffer;
-    if (!ArrayBufferView::verifySubRange<typename Adaptor::Type>(buffer, byteOffset, length)) {
-        exec->vm().throwException(
-            exec, createRangeError(exec, "Byte offset and length out of range of buffer"));
-        return 0;
+    size_t size = sizeof(typename Adaptor::Type);
+    if (!ArrayBufferView::verifySubRangeLength(buffer, byteOffset, length, size)) {
+        exec->vm().throwException(exec, createRangeError(exec, "Length out of range of buffer"));
+        return nullptr;
     }
+    if (!ArrayBufferView::verifyByteOffsetAlignment(byteOffset, size)) {
+        exec->vm().throwException(exec, createRangeError(exec, "Byte offset is not aligned"));
+        return nullptr;
+    }
     ConstructionContext context(exec->vm(), structure, buffer, byteOffset, length);
     ASSERT(context);
     JSGenericTypedArrayView* result =
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to