2010-03-01 Kenneth Russell <kbr@google.com>
authorkbr@google.com <kbr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Mar 2010 21:20:31 +0000 (21:20 +0000)
committerkbr@google.com <kbr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Mar 2010 21:20:31 +0000 (21:20 +0000)
        Reviewed by Oliver Hunt.

        Integer overflow in WebGL arrays
        https://bugs.webkit.org/show_bug.cgi?id=35241

        Test: fast/canvas/webgl/webgl-array-invalid-ranges.html

        * bindings/js/JSWebGLArrayBufferConstructor.cpp:
        (WebCore::constructCanvasArrayBuffer):
        * bindings/js/JSWebGLArrayBufferConstructor.h:
        (WebCore::construct):
        * bindings/js/JSWebGLArrayHelper.h:
        (WebCore::setWebGLArrayFromArray):
        * bindings/js/JSWebGLByteArrayConstructor.cpp:
        (WebCore::constructCanvasByteArray):
        * bindings/js/JSWebGLFloatArrayConstructor.cpp:
        (WebCore::constructCanvasFloatArray):
        * bindings/js/JSWebGLIntArrayConstructor.cpp:
        (WebCore::constructCanvasIntArray):
        * bindings/js/JSWebGLShortArrayConstructor.cpp:
        (WebCore::constructCanvasShortArray):
        * bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp:
        (WebCore::constructCanvasUnsignedByteArray):
        * bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp:
        (WebCore::constructCanvasUnsignedIntArray):
        * bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp:
        (WebCore::constructCanvasUnsignedShortArray):
        * bindings/v8/V8Binding.cpp:
        (WebCore::toUInt32):
        * bindings/v8/V8Binding.h:
        (WebCore::toUInt32):
        * bindings/v8/custom/V8WebGLArrayBufferCustom.cpp:
        (WebCore::V8WebGLArrayBuffer::constructorCallback):
        * bindings/v8/custom/V8WebGLArrayCustom.h:
        (WebCore::constructWebGLArray):
        (WebCore::getWebGLArrayElement):
        (WebCore::setWebGLArrayFromArray):
        (WebCore::setWebGLArray):
        * bindings/v8/custom/V8WebGLByteArrayCustom.cpp:
        (WebCore::V8WebGLByteArray::constructorCallback):
        * bindings/v8/custom/V8WebGLFloatArrayCustom.cpp:
        (WebCore::V8WebGLFloatArray::constructorCallback):
        * bindings/v8/custom/V8WebGLIntArrayCustom.cpp:
        (WebCore::V8WebGLIntArray::constructorCallback):
        * bindings/v8/custom/V8WebGLShortArrayCustom.cpp:
        (WebCore::V8WebGLShortArray::constructorCallback):
        * bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp:
        (WebCore::V8WebGLUnsignedByteArray::constructorCallback):
        * bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp:
        (WebCore::V8WebGLUnsignedIntArray::constructorCallback):
        * bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp:
        (WebCore::V8WebGLUnsignedShortArray::constructorCallback):
        * html/canvas/WebGLArray.cpp:
        (WebCore::WebGLArray::setImpl):
        * html/canvas/WebGLArray.h:
        (WebCore::WebGLArray::verifySubRange):
        (WebCore::WebGLArray::clampOffsetAndNumElements):
        * html/canvas/WebGLArrayBuffer.cpp:
        (WebCore::WebGLArrayBuffer::create):
        (WebCore::WebGLArrayBuffer::WebGLArrayBuffer):
        (WebCore::WebGLArrayBuffer::tryAllocate):
        * html/canvas/WebGLArrayBuffer.h:
        * html/canvas/WebGLByteArray.cpp:
        (WebCore::WebGLByteArray::create):
        (WebCore::WebGLByteArray::WebGLByteArray):
        (WebCore::WebGLByteArray::slice):
        * html/canvas/WebGLByteArray.h:
        * html/canvas/WebGLFloatArray.cpp:
        (WebCore::WebGLFloatArray::create):
        (WebCore::WebGLFloatArray::WebGLFloatArray):
        (WebCore::WebGLFloatArray::slice):
        * html/canvas/WebGLFloatArray.h:
        * html/canvas/WebGLIntArray.cpp:
        (WebCore::WebGLIntArray::create):
        (WebCore::WebGLIntArray::WebGLIntArray):
        (WebCore::WebGLIntArray::slice):
        * html/canvas/WebGLIntArray.h:
        * html/canvas/WebGLShortArray.cpp:
        (WebCore::WebGLShortArray::create):
        (WebCore::WebGLShortArray::WebGLShortArray):
        (WebCore::WebGLShortArray::slice):
        * html/canvas/WebGLShortArray.h:
        * html/canvas/WebGLUnsignedByteArray.cpp:
        (WebCore::WebGLUnsignedByteArray::create):
        (WebCore::WebGLUnsignedByteArray::WebGLUnsignedByteArray):
        (WebCore::WebGLUnsignedByteArray::slice):
        * html/canvas/WebGLUnsignedByteArray.h:
        * html/canvas/WebGLUnsignedIntArray.cpp:
        (WebCore::WebGLUnsignedIntArray::create):
        (WebCore::WebGLUnsignedIntArray::WebGLUnsignedIntArray):
        (WebCore::WebGLUnsignedIntArray::slice):
        * html/canvas/WebGLUnsignedIntArray.h:
        * html/canvas/WebGLUnsignedShortArray.cpp:
        (WebCore::WebGLUnsignedShortArray::create):
        (WebCore::WebGLUnsignedShortArray::WebGLUnsignedShortArray):
        (WebCore::WebGLUnsignedShortArray::slice):
        * html/canvas/WebGLUnsignedShortArray.h:

2010-03-01  Kenneth Russell  <kbr@google.com>

        Reviewed by Oliver Hunt.

        Integer overflow in WebGL arrays
        https://bugs.webkit.org/show_bug.cgi?id=35241

        * fast/canvas/webgl/array-unit-tests-expected.txt:
        * fast/canvas/webgl/array-unit-tests.html:
        * fast/canvas/webgl/webgl-array-invalid-ranges-expected.txt: Added.
        * fast/canvas/webgl/webgl-array-invalid-ranges.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@55376 268f45cc-cd09-0410-ab3c-d52691b4dbfc

45 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/array-unit-tests-expected.txt
LayoutTests/fast/canvas/webgl/array-unit-tests.html
LayoutTests/fast/canvas/webgl/webgl-array-invalid-ranges-expected.txt [new file with mode: 0644]
LayoutTests/fast/canvas/webgl/webgl-array-invalid-ranges.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/bindings/js/JSWebGLArrayBufferConstructor.cpp
WebCore/bindings/js/JSWebGLArrayBufferConstructor.h
WebCore/bindings/js/JSWebGLArrayHelper.h
WebCore/bindings/js/JSWebGLByteArrayConstructor.cpp
WebCore/bindings/js/JSWebGLFloatArrayConstructor.cpp
WebCore/bindings/js/JSWebGLIntArrayConstructor.cpp
WebCore/bindings/js/JSWebGLShortArrayConstructor.cpp
WebCore/bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp
WebCore/bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp
WebCore/bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp
WebCore/bindings/v8/V8Binding.cpp
WebCore/bindings/v8/V8Binding.h
WebCore/bindings/v8/custom/V8WebGLArrayBufferCustom.cpp
WebCore/bindings/v8/custom/V8WebGLArrayCustom.h
WebCore/bindings/v8/custom/V8WebGLByteArrayCustom.cpp
WebCore/bindings/v8/custom/V8WebGLFloatArrayCustom.cpp
WebCore/bindings/v8/custom/V8WebGLIntArrayCustom.cpp
WebCore/bindings/v8/custom/V8WebGLShortArrayCustom.cpp
WebCore/bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp
WebCore/bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp
WebCore/bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp
WebCore/html/canvas/WebGLArray.cpp
WebCore/html/canvas/WebGLArray.h
WebCore/html/canvas/WebGLArrayBuffer.cpp
WebCore/html/canvas/WebGLArrayBuffer.h
WebCore/html/canvas/WebGLByteArray.cpp
WebCore/html/canvas/WebGLByteArray.h
WebCore/html/canvas/WebGLFloatArray.cpp
WebCore/html/canvas/WebGLFloatArray.h
WebCore/html/canvas/WebGLIntArray.cpp
WebCore/html/canvas/WebGLIntArray.h
WebCore/html/canvas/WebGLShortArray.cpp
WebCore/html/canvas/WebGLShortArray.h
WebCore/html/canvas/WebGLUnsignedByteArray.cpp
WebCore/html/canvas/WebGLUnsignedByteArray.h
WebCore/html/canvas/WebGLUnsignedIntArray.cpp
WebCore/html/canvas/WebGLUnsignedIntArray.h
WebCore/html/canvas/WebGLUnsignedShortArray.cpp
WebCore/html/canvas/WebGLUnsignedShortArray.h

index 3cec27b..0874d12 100644 (file)
@@ -1,3 +1,15 @@
+2010-03-01  Kenneth Russell  <kbr@google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Integer overflow in WebGL arrays
+        https://bugs.webkit.org/show_bug.cgi?id=35241
+
+        * fast/canvas/webgl/array-unit-tests-expected.txt:
+        * fast/canvas/webgl/array-unit-tests.html:
+        * fast/canvas/webgl/webgl-array-invalid-ranges-expected.txt: Added.
+        * fast/canvas/webgl/webgl-array-invalid-ranges.html: Added.
+
 2010-03-01  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Sam Weinig.
index e297d1c..8ca0b89 100644 (file)
@@ -14,6 +14,16 @@ PASS negativeTest WebGLByteArray SetFromArray
 PASS test WebGLByteArray Slice
 PASS negativeTest WebGLByteArray Slice
 PASS test WebGLByteArray BoundaryConditions(-128, -128, 127, 127)
+PASS Construction of WebGLByteArray with null buffer threw exception
+PASS Construction of WebGLByteArray with out-of-range values threw exception
+PASS Construction of WebGLByteArray with negative out-of-range values threw exception
+Testing slicing of WebGLByteArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLByteArray from array with out-of-range offset was caught
+PASS Setting WebGLByteArray from fake array with invalid length was caught
+PASS Setting WebGLByteArray from WebGLByteArray with out-of-range offset was caught
 PASS test WebGLFloatArray SetAndGetPos10ToNeg10
 PASS test WebGLFloatArray SetAndGetMethodsPos10ToNeg10
 PASS test WebGLFloatArray ConstructWithArrayOfSignedValues
@@ -26,6 +36,17 @@ PASS negativeTest WebGLFloatArray SetFromArray
 PASS test WebGLFloatArray Slice
 PASS negativeTest WebGLFloatArray Slice
 PASS test WebGLFloatArray BoundaryConditions(-500.5, -500.5, 500.5, 500.5)
+PASS Construction of WebGLFloatArray with null buffer threw exception
+PASS Construction of WebGLFloatArray with out-of-range values threw exception
+PASS Construction of WebGLFloatArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLFloatArray threw exception
+Testing slicing of WebGLFloatArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLFloatArray from array with out-of-range offset was caught
+PASS Setting WebGLFloatArray from fake array with invalid length was caught
+PASS Setting WebGLFloatArray from WebGLFloatArray with out-of-range offset was caught
 PASS test WebGLIntArray SetAndGetPos10ToNeg10
 PASS test WebGLIntArray SetAndGetMethodsPos10ToNeg10
 PASS test WebGLIntArray ConstructWithArrayOfSignedValues
@@ -38,6 +59,17 @@ PASS negativeTest WebGLIntArray SetFromArray
 PASS test WebGLIntArray Slice
 PASS negativeTest WebGLIntArray Slice
 PASS test WebGLIntArray BoundaryConditions(-2147483648, -2147483648, 2147483647, 2147483647)
+PASS Construction of WebGLIntArray with null buffer threw exception
+PASS Construction of WebGLIntArray with out-of-range values threw exception
+PASS Construction of WebGLIntArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLIntArray threw exception
+Testing slicing of WebGLIntArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLIntArray from array with out-of-range offset was caught
+PASS Setting WebGLIntArray from fake array with invalid length was caught
+PASS Setting WebGLIntArray from WebGLIntArray with out-of-range offset was caught
 PASS test WebGLShortArray SetAndGetPos10ToNeg10
 PASS test WebGLShortArray SetAndGetMethodsPos10ToNeg10
 PASS test WebGLShortArray ConstructWithArrayOfSignedValues
@@ -50,6 +82,17 @@ PASS negativeTest WebGLShortArray SetFromArray
 PASS test WebGLShortArray Slice
 PASS negativeTest WebGLShortArray Slice
 PASS test WebGLShortArray BoundaryConditions(-32768, -32768, 32767, 32767)
+PASS Construction of WebGLShortArray with null buffer threw exception
+PASS Construction of WebGLShortArray with out-of-range values threw exception
+PASS Construction of WebGLShortArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLShortArray threw exception
+Testing slicing of WebGLShortArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLShortArray from array with out-of-range offset was caught
+PASS Setting WebGLShortArray from fake array with invalid length was caught
+PASS Setting WebGLShortArray from WebGLShortArray with out-of-range offset was caught
 PASS test WebGLUnsignedByteArray SetAndGet10To1
 PASS test WebGLUnsignedByteArray SetAndGetMethods10To1
 PASS test WebGLUnsignedByteArray ConstructWithArrayOfUnsignedValues
@@ -62,6 +105,16 @@ PASS negativeTest WebGLUnsignedByteArray SetFromArray
 PASS test WebGLUnsignedByteArray Slice
 PASS negativeTest WebGLUnsignedByteArray Slice
 PASS test WebGLUnsignedByteArray BoundaryConditions(0, 0, 255, 255)
+PASS Construction of WebGLUnsignedByteArray with null buffer threw exception
+PASS Construction of WebGLUnsignedByteArray with out-of-range values threw exception
+PASS Construction of WebGLUnsignedByteArray with negative out-of-range values threw exception
+Testing slicing of WebGLUnsignedByteArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLUnsignedByteArray from array with out-of-range offset was caught
+PASS Setting WebGLUnsignedByteArray from fake array with invalid length was caught
+PASS Setting WebGLUnsignedByteArray from WebGLUnsignedByteArray with out-of-range offset was caught
 PASS test WebGLUnsignedIntArray SetAndGet10To1
 PASS test WebGLUnsignedIntArray SetAndGetMethods10To1
 PASS test WebGLUnsignedIntArray ConstructWithArrayOfUnsignedValues
@@ -74,6 +127,17 @@ PASS negativeTest WebGLUnsignedIntArray SetFromArray
 PASS test WebGLUnsignedIntArray Slice
 PASS negativeTest WebGLUnsignedIntArray Slice
 PASS test WebGLUnsignedIntArray BoundaryConditions(0, 0, 4294967295, 4294967295)
+PASS Construction of WebGLUnsignedIntArray with null buffer threw exception
+PASS Construction of WebGLUnsignedIntArray with out-of-range values threw exception
+PASS Construction of WebGLUnsignedIntArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLUnsignedIntArray threw exception
+Testing slicing of WebGLUnsignedIntArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLUnsignedIntArray from array with out-of-range offset was caught
+PASS Setting WebGLUnsignedIntArray from fake array with invalid length was caught
+PASS Setting WebGLUnsignedIntArray from WebGLUnsignedIntArray with out-of-range offset was caught
 PASS test WebGLUnsignedShortArray SetAndGet10To1
 PASS test WebGLUnsignedShortArray SetAndGetMethods10To1
 PASS test WebGLUnsignedShortArray ConstructWithArrayOfUnsignedValues
@@ -86,6 +150,17 @@ PASS negativeTest WebGLUnsignedShortArray SetFromArray
 PASS test WebGLUnsignedShortArray Slice
 PASS negativeTest WebGLUnsignedShortArray Slice
 PASS test WebGLUnsignedShortArray BoundaryConditions(0, 0, 65535, 65535)
+PASS Construction of WebGLUnsignedShortArray with null buffer threw exception
+PASS Construction of WebGLUnsignedShortArray with out-of-range values threw exception
+PASS Construction of WebGLUnsignedShortArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLUnsignedShortArray threw exception
+Testing slicing of WebGLUnsignedShortArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLUnsignedShortArray from array with out-of-range offset was caught
+PASS Setting WebGLUnsignedShortArray from fake array with invalid length was caught
+PASS Setting WebGLUnsignedShortArray from WebGLUnsignedShortArray with out-of-range offset was caught
 Test passed.
 PASS successfullyParsed is true
 
index 6aeac5e..3e354cc 100644 (file)
@@ -331,18 +331,18 @@ function negativeTestSlice(type, name) {
   try {
     var array = new type([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
     slice = array.slice(5, 6);
-    if (slice) {
+    if (slice.length != 5) {
       fail();
       return;
     }
     slice = array.slice(10, 0);
-    if (slice) {
+    if (slice.length != 0) {
       fail();
       return;
     }
     pass();
   } catch (e) {
-    pass();
+    fail(e);
   }
 }
 
@@ -368,6 +368,114 @@ function testBoundaryConditions(type, name, lowValue, expectedLowValue, highValu
   }
 }
 
+function testConstructionWithNullBuffer(type, name) {
+    var array;
+    try {
+        array = new type(null, 0, 0);
+        testFailed("Construction of " + name + " with null buffer should throw exception");
+    } catch (e) {
+        testPassed("Construction of " + name + " with null buffer threw exception");
+    }
+}
+
+
+function testConstructionWithOutOfRangeValues(type, name) {
+    var buffer = new WebGLArrayBuffer(4);
+    var array;
+    try {
+        array = new type(buffer, 4, 0x3FFFFFFF);
+        testFailed("Construction of " + name + " with out-of-range values should throw exception");
+    } catch (e) {
+        testPassed("Construction of " + name + " with out-of-range values threw exception");
+    }
+}
+
+function testConstructionWithNegativeOutOfRangeValues(type, name) {
+    var buffer = new WebGLArrayBuffer(4);
+    var array;
+    try {
+        array = new type(buffer, 4, -2147483648);
+        testFailed("Construction of " + name + " with negative out-of-range values should throw exception");
+    } catch (e) {
+        testPassed("Construction of " + name + " with negative out-of-range values threw exception");
+    }
+}
+
+function testConstructionOfHugeArray(type, name, sz) {
+    if (sz == 1)
+        return;
+    try {
+        // Construction of huge arrays must fail because byteLength is
+        // an unsigned long
+        array = new type(3000000000);
+        testFailed("Construction of huge " + name + " should throw exception");
+    } catch (e) {
+        testPassed("Construction of huge " + name + " threw exception");
+    }
+}
+
+// These need to be global for shouldBe to see them
+var array;
+var typeSize;
+
+function testSlicingWithOutOfRangeValues(type, name, sz) {
+    debug("Testing slicing of " + name);
+    try {
+        var buffer = new WebGLArrayBuffer(32);
+        array = new type(buffer);
+        typeSize = sz;
+        shouldBe("array.length", "32 / typeSize");
+        try {
+            shouldBe("array.slice(4, 0x3FFFFFFF).length", "(32 / typeSize) - 4");
+            shouldBe("array.slice(4, -2147483648).length", "(32 / typeSize) - 4");
+        } catch (e) {
+            testFailed("Slicing of " + name + " threw exception");
+        }
+    } catch (e) {
+        testFailed("Exception: " + e);
+    }
+}
+
+function testSettingFromArrayWithOutOfRangeOffset(type, name) {
+    var webglArray = new type(32);
+    var array = [];
+    for (var i = 0; i < 16; i++) {
+        array.push(i);
+    }
+    try {
+        webglArray.set(array, 0x7FFFFFF8);
+        testFailed("Setting " + name + " from array with out-of-range offset was not caught");
+    } catch (e) {
+        testPassed("Setting " + name + " from array with out-of-range offset was caught");
+    }
+}
+
+function testSettingFromFakeArrayWithOutOfRangeLength(type, name) {
+    var webglArray = new type(32);
+    var array = {};
+    array.length = 0x80000000;
+    try {
+        webglArray.set(array, 8);
+        testFailed("Setting " + name + " from fake array with invalid length was not caught");
+    } catch (e) {
+        testPassed("Setting " + name + " from fake array with invalid length was caught");
+    }
+}
+
+function testSettingFromWebGLArrayWithOutOfRangeOffset(type, name) {
+    var webglArray = new type(32);
+    var srcArray = new type(16);
+    for (var i = 0; i < 16; i++) {
+        srcArray[i] = i;
+    }
+    try {
+        webglArray.set(srcArray, 0x7FFFFFF8);
+        testFailed("Setting " + name + " from " + name + " with out-of-range offset was not caught");
+    } catch (e) {
+        testPassed("Setting " + name + " from " + name + " with out-of-range offset was caught");
+    }
+}
+
 //
 // Test driver
 //
@@ -461,6 +569,14 @@ function runTests() {
                            testCase.expectedLow,
                            testCase.high,
                            testCase.expectedHigh);
+    testConstructionWithNullBuffer(type, name);
+    testConstructionWithOutOfRangeValues(type, name);
+    testConstructionWithNegativeOutOfRangeValues(type, name);
+    testConstructionOfHugeArray(type, name, testCase.elementSizeInBytes);
+    testSlicingWithOutOfRangeValues(type, name, testCase.elementSizeInBytes);
+    testSettingFromArrayWithOutOfRangeOffset(type, name);
+    testSettingFromFakeArrayWithOutOfRangeLength(type, name);
+    testSettingFromWebGLArrayWithOutOfRangeOffset(type, name);
   }
 
   printSummary();
diff --git a/LayoutTests/fast/canvas/webgl/webgl-array-invalid-ranges-expected.txt b/LayoutTests/fast/canvas/webgl/webgl-array-invalid-ranges-expected.txt
new file mode 100644 (file)
index 0000000..cd5570c
--- /dev/null
@@ -0,0 +1,83 @@
+Verifies that out-of-range parameters for creation, slicing and setting of WebGL arrays are caught
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Construction of WebGLByteArray with null buffer threw exception
+PASS Construction of WebGLByteArray with out-of-range values threw exception
+PASS Construction of WebGLByteArray with negative out-of-range values threw exception
+Testing slicing of WebGLByteArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLByteArray from array with out-of-range offset was caught
+PASS Setting WebGLByteArray from fake array with invalid length was caught
+PASS Setting WebGLByteArray from WebGLByteArray with out-of-range offset was caught
+PASS Construction of WebGLUnsignedByteArray with null buffer threw exception
+PASS Construction of WebGLUnsignedByteArray with out-of-range values threw exception
+PASS Construction of WebGLUnsignedByteArray with negative out-of-range values threw exception
+Testing slicing of WebGLUnsignedByteArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLUnsignedByteArray from array with out-of-range offset was caught
+PASS Setting WebGLUnsignedByteArray from fake array with invalid length was caught
+PASS Setting WebGLUnsignedByteArray from WebGLUnsignedByteArray with out-of-range offset was caught
+PASS Construction of WebGLShortArray with null buffer threw exception
+PASS Construction of WebGLShortArray with out-of-range values threw exception
+PASS Construction of WebGLShortArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLShortArray threw exception
+Testing slicing of WebGLShortArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLShortArray from array with out-of-range offset was caught
+PASS Setting WebGLShortArray from fake array with invalid length was caught
+PASS Setting WebGLShortArray from WebGLShortArray with out-of-range offset was caught
+PASS Construction of WebGLUnsignedShortArray with null buffer threw exception
+PASS Construction of WebGLUnsignedShortArray with out-of-range values threw exception
+PASS Construction of WebGLUnsignedShortArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLUnsignedShortArray threw exception
+Testing slicing of WebGLUnsignedShortArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLUnsignedShortArray from array with out-of-range offset was caught
+PASS Setting WebGLUnsignedShortArray from fake array with invalid length was caught
+PASS Setting WebGLUnsignedShortArray from WebGLUnsignedShortArray with out-of-range offset was caught
+PASS Construction of WebGLIntArray with null buffer threw exception
+PASS Construction of WebGLIntArray with out-of-range values threw exception
+PASS Construction of WebGLIntArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLIntArray threw exception
+Testing slicing of WebGLIntArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLIntArray from array with out-of-range offset was caught
+PASS Setting WebGLIntArray from fake array with invalid length was caught
+PASS Setting WebGLIntArray from WebGLIntArray with out-of-range offset was caught
+PASS Construction of WebGLUnsignedIntArray with null buffer threw exception
+PASS Construction of WebGLUnsignedIntArray with out-of-range values threw exception
+PASS Construction of WebGLUnsignedIntArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLUnsignedIntArray threw exception
+Testing slicing of WebGLUnsignedIntArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLUnsignedIntArray from array with out-of-range offset was caught
+PASS Setting WebGLUnsignedIntArray from fake array with invalid length was caught
+PASS Setting WebGLUnsignedIntArray from WebGLUnsignedIntArray with out-of-range offset was caught
+PASS Construction of WebGLFloatArray with null buffer threw exception
+PASS Construction of WebGLFloatArray with out-of-range values threw exception
+PASS Construction of WebGLFloatArray with negative out-of-range values threw exception
+PASS Construction of huge WebGLFloatArray threw exception
+Testing slicing of WebGLFloatArray
+PASS array.length is 32 / typeSize
+PASS array.slice(4, 0x3FFFFFFF).length is (32 / typeSize) - 4
+PASS array.slice(4, -2147483648).length is (32 / typeSize) - 4
+PASS Setting WebGLFloatArray from array with out-of-range offset was caught
+PASS Setting WebGLFloatArray from fake array with invalid length was caught
+PASS Setting WebGLFloatArray from WebGLFloatArray with out-of-range offset was caught
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/webgl-array-invalid-ranges.html b/LayoutTests/fast/canvas/webgl/webgl-array-invalid-ranges.html
new file mode 100644 (file)
index 0000000..d67a5dc
--- /dev/null
@@ -0,0 +1,156 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+
+description("Verifies that out-of-range parameters for creation, slicing and setting of WebGL arrays are caught");
+
+function testConstructionWithNullBuffer(type, name) {
+    var array;
+    try {
+        array = new type(null, 0, 0);
+        testFailed("Construction of " + name + " with null buffer should throw exception");
+    } catch (e) {
+        testPassed("Construction of " + name + " with null buffer threw exception");
+    }
+}
+
+
+function testConstructionWithOutOfRangeValues(type, name) {
+    var buffer = new WebGLArrayBuffer(4);
+    var array;
+    try {
+        array = new type(buffer, 4, 0x3FFFFFFF);
+        testFailed("Construction of " + name + " with out-of-range values should throw exception");
+    } catch (e) {
+        testPassed("Construction of " + name + " with out-of-range values threw exception");
+    }
+}
+
+function testConstructionWithNegativeOutOfRangeValues(type, name) {
+    var buffer = new WebGLArrayBuffer(4);
+    var array;
+    try {
+        array = new type(buffer, 4, -2147483648);
+        testFailed("Construction of " + name + " with negative out-of-range values should throw exception");
+    } catch (e) {
+        testPassed("Construction of " + name + " with negative out-of-range values threw exception");
+    }
+}
+
+function testConstructionOfHugeArray(type, name, sz) {
+    if (sz == 1)
+        return;
+    try {
+        // Construction of huge arrays must fail because byteLength is
+        // an unsigned long
+        array = new type(3000000000);
+        testFailed("Construction of huge " + name + " should throw exception");
+    } catch (e) {
+        testPassed("Construction of huge " + name + " threw exception");
+    }
+}
+
+// These need to be global for shouldBe to see them
+var array;
+var typeSize;
+
+function testSlicingWithOutOfRangeValues(type, name, sz) {
+    debug("Testing slicing of " + name);
+    try {
+        var buffer = new WebGLArrayBuffer(32);
+        array = new type(buffer);
+        typeSize = sz;
+        shouldBe("array.length", "32 / typeSize");
+        try {
+            shouldBe("array.slice(4, 0x3FFFFFFF).length", "(32 / typeSize) - 4");
+            shouldBe("array.slice(4, -2147483648).length", "(32 / typeSize) - 4");
+        } catch (e) {
+            testFailed("Slicing of " + name + " threw exception");
+        }
+    } catch (e) {
+        testFailed("Exception: " + e);
+    }
+}
+
+function testSettingFromArrayWithOutOfRangeOffset(type, name) {
+    var webglArray = new type(32);
+    var array = [];
+    for (var i = 0; i < 16; i++) {
+        array.push(i);
+    }
+    try {
+        webglArray.set(array, 0x7FFFFFF8);
+        testFailed("Setting " + name + " from array with out-of-range offset was not caught");
+    } catch (e) {
+        testPassed("Setting " + name + " from array with out-of-range offset was caught");
+    }
+}
+
+function testSettingFromFakeArrayWithOutOfRangeLength(type, name) {
+    var webglArray = new type(32);
+    var array = {};
+    array.length = 0x80000000;
+    try {
+        webglArray.set(array, 8);
+        testFailed("Setting " + name + " from fake array with invalid length was not caught");
+    } catch (e) {
+        testPassed("Setting " + name + " from fake array with invalid length was caught");
+    }
+}
+
+function testSettingFromWebGLArrayWithOutOfRangeOffset(type, name) {
+    var webglArray = new type(32);
+    var srcArray = new type(16);
+    for (var i = 0; i < 16; i++) {
+        srcArray[i] = i;
+    }
+    try {
+        webglArray.set(srcArray, 0x7FFFFFF8);
+        testFailed("Setting " + name + " from " + name + " with out-of-range offset was not caught");
+    } catch (e) {
+        testPassed("Setting " + name + " from " + name + " with out-of-range offset was caught");
+    }
+}
+
+var typeNames = [ "WebGLByteArray",
+                  "WebGLUnsignedByteArray",
+                  "WebGLShortArray",
+                  "WebGLUnsignedShortArray",
+                  "WebGLIntArray",
+                  "WebGLUnsignedIntArray",
+                  "WebGLFloatArray" ];
+
+var typeSizes = [ 1, 1, 2, 2, 4, 4, 4 ];
+
+for (var i = 0; i < typeNames.length; i++) {
+    var name = typeNames[i];
+    var type = window[name];
+    if (!type) {
+        testFailed("Could not find array type " + name);
+    } else {
+        testConstructionWithNullBuffer(type, name);
+        testConstructionWithOutOfRangeValues(type, name);
+        testConstructionWithNegativeOutOfRangeValues(type, name);
+        testConstructionOfHugeArray(type, name, typeSizes[i]);
+        testSlicingWithOutOfRangeValues(type, name, typeSizes[i]);
+        testSettingFromArrayWithOutOfRangeOffset(type, name);
+        testSettingFromFakeArrayWithOutOfRangeLength(type, name);
+        testSettingFromWebGLArrayWithOutOfRangeOffset(type, name);
+    }
+}
+
+successfullyParsed = true;
+
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+
+</body>
+</html>
index 1cd15df..dec3042 100644 (file)
@@ -1,3 +1,103 @@
+2010-03-01  Kenneth Russell  <kbr@google.com>
+
+        Reviewed by Oliver Hunt.
+
+        Integer overflow in WebGL arrays
+        https://bugs.webkit.org/show_bug.cgi?id=35241
+
+        Test: fast/canvas/webgl/webgl-array-invalid-ranges.html
+
+        * bindings/js/JSWebGLArrayBufferConstructor.cpp:
+        (WebCore::constructCanvasArrayBuffer):
+        * bindings/js/JSWebGLArrayBufferConstructor.h:
+        (WebCore::construct):
+        * bindings/js/JSWebGLArrayHelper.h:
+        (WebCore::setWebGLArrayFromArray):
+        * bindings/js/JSWebGLByteArrayConstructor.cpp:
+        (WebCore::constructCanvasByteArray):
+        * bindings/js/JSWebGLFloatArrayConstructor.cpp:
+        (WebCore::constructCanvasFloatArray):
+        * bindings/js/JSWebGLIntArrayConstructor.cpp:
+        (WebCore::constructCanvasIntArray):
+        * bindings/js/JSWebGLShortArrayConstructor.cpp:
+        (WebCore::constructCanvasShortArray):
+        * bindings/js/JSWebGLUnsignedByteArrayConstructor.cpp:
+        (WebCore::constructCanvasUnsignedByteArray):
+        * bindings/js/JSWebGLUnsignedIntArrayConstructor.cpp:
+        (WebCore::constructCanvasUnsignedIntArray):
+        * bindings/js/JSWebGLUnsignedShortArrayConstructor.cpp:
+        (WebCore::constructCanvasUnsignedShortArray):
+        * bindings/v8/V8Binding.cpp:
+        (WebCore::toUInt32):
+        * bindings/v8/V8Binding.h:
+        (WebCore::toUInt32):
+        * bindings/v8/custom/V8WebGLArrayBufferCustom.cpp:
+        (WebCore::V8WebGLArrayBuffer::constructorCallback):
+        * bindings/v8/custom/V8WebGLArrayCustom.h:
+        (WebCore::constructWebGLArray):
+        (WebCore::getWebGLArrayElement):
+        (WebCore::setWebGLArrayFromArray):
+        (WebCore::setWebGLArray):
+        * bindings/v8/custom/V8WebGLByteArrayCustom.cpp:
+        (WebCore::V8WebGLByteArray::constructorCallback):
+        * bindings/v8/custom/V8WebGLFloatArrayCustom.cpp:
+        (WebCore::V8WebGLFloatArray::constructorCallback):
+        * bindings/v8/custom/V8WebGLIntArrayCustom.cpp:
+        (WebCore::V8WebGLIntArray::constructorCallback):
+        * bindings/v8/custom/V8WebGLShortArrayCustom.cpp:
+        (WebCore::V8WebGLShortArray::constructorCallback):
+        * bindings/v8/custom/V8WebGLUnsignedByteArrayCustom.cpp:
+        (WebCore::V8WebGLUnsignedByteArray::constructorCallback):
+        * bindings/v8/custom/V8WebGLUnsignedIntArrayCustom.cpp:
+        (WebCore::V8WebGLUnsignedIntArray::constructorCallback):
+        * bindings/v8/custom/V8WebGLUnsignedShortArrayCustom.cpp:
+        (WebCore::V8WebGLUnsignedShortArray::constructorCallback):
+        * html/canvas/WebGLArray.cpp:
+        (WebCore::WebGLArray::setImpl):
+        * html/canvas/WebGLArray.h:
+        (WebCore::WebGLArray::verifySubRange):
+        (WebCore::WebGLArray::clampOffsetAndNumElements):
+        * html/canvas/WebGLArrayBuffer.cpp:
+        (WebCore::WebGLArrayBuffer::create):
+        (WebCore::WebGLArrayBuffer::WebGLArrayBuffer):
+        (WebCore::WebGLArrayBuffer::tryAllocate):
+        * html/canvas/WebGLArrayBuffer.h:
+        * html/canvas/WebGLByteArray.cpp:
+        (WebCore::WebGLByteArray::create):
+        (WebCore::WebGLByteArray::WebGLByteArray):
+        (WebCore::WebGLByteArray::slice):
+        * html/canvas/WebGLByteArray.h:
+        * html/canvas/WebGLFloatArray.cpp:
+        (WebCore::WebGLFloatArray::create):
+        (WebCore::WebGLFloatArray::WebGLFloatArray):
+        (WebCore::WebGLFloatArray::slice):
+        * html/canvas/WebGLFloatArray.h:
+        * html/canvas/WebGLIntArray.cpp:
+        (WebCore::WebGLIntArray::create):
+        (WebCore::WebGLIntArray::WebGLIntArray):
+        (WebCore::WebGLIntArray::slice):
+        * html/canvas/WebGLIntArray.h:
+        * html/canvas/WebGLShortArray.cpp:
+        (WebCore::WebGLShortArray::create):
+        (WebCore::WebGLShortArray::WebGLShortArray):
+        (WebCore::WebGLShortArray::slice):
+        * html/canvas/WebGLShortArray.h:
+        * html/canvas/WebGLUnsignedByteArray.cpp:
+        (WebCore::WebGLUnsignedByteArray::create):
+        (WebCore::WebGLUnsignedByteArray::WebGLUnsignedByteArray):
+        (WebCore::WebGLUnsignedByteArray::slice):
+        * html/canvas/WebGLUnsignedByteArray.h:
+        * html/canvas/WebGLUnsignedIntArray.cpp:
+        (WebCore::WebGLUnsignedIntArray::create):
+        (WebCore::WebGLUnsignedIntArray::WebGLUnsignedIntArray):
+        (WebCore::WebGLUnsignedIntArray::slice):
+        * html/canvas/WebGLUnsignedIntArray.h:
+        * html/canvas/WebGLUnsignedShortArray.cpp:
+        (WebCore::WebGLUnsignedShortArray::create):
+        (WebCore::WebGLUnsignedShortArray::WebGLUnsignedShortArray):
+        (WebCore::WebGLUnsignedShortArray::slice):
+        * html/canvas/WebGLUnsignedShortArray.h:
+
 2010-03-01  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Sam Weinig.
index 9742db7..8671908 100644 (file)
@@ -30,7 +30,6 @@
 #include "JSWebGLArrayBufferConstructor.h"
 
 #include "Document.h"
-#include "WebGLArrayBuffer.h"
 #include "JSWebGLArrayBuffer.h"
 
 namespace WebCore {
@@ -56,7 +55,12 @@ static JSObject* constructCanvasArrayBuffer(ExecState* exec, JSObject* construct
         if (isnan(size))
             size = 0;
     }
-    return asObject(toJS(exec, jsConstructor->globalObject(), WebGLArrayBuffer::create(size)));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(size, 1);
+    if (!buffer.get()){
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
+    return asObject(toJS(exec, jsConstructor->globalObject(), buffer.get()));
 }
 
 JSC::ConstructType JSWebGLArrayBufferConstructor::getConstructData(JSC::ConstructData& constructData)
index 98e364b..c7a927e 100644 (file)
@@ -30,6 +30,7 @@
 #include "JSDocument.h"
 #include "JSWebGLArrayBuffer.h"
 #include <runtime/Error.h>
+#include "WebGLArrayBuffer.h"
 
 namespace WebCore {
 
@@ -51,24 +52,30 @@ namespace WebCore {
         if (args.size() < 1)
             return C::create(0, 0, 0);
         
+        if (args.size() > 1 && !args.at(0).isObject())
+            // Invalid first argument
+            return 0;
+
         if (args.at(0).isObject()) {
             RefPtr<WebGLArrayBuffer> buffer = toWebGLArrayBuffer(args.at(0));
             if (buffer) {
-                int offset = (args.size() > 1) ? args.at(1).toInt32(exec) : 0;
-                unsigned int length = (args.size() > 2) ? static_cast<unsigned int>(args.at(2).toInt32(exec)) : 0;
+                unsigned offset = (args.size() > 1) ? args.at(1).toUInt32(exec) : 0;
+                unsigned int length = (buffer->byteLength() - offset) / sizeof(T);
+                if (args.size() > 2)
+                    length = args.at(2).toUInt32(exec);
                 return C::create(buffer, offset, length);
             }
             
             JSC::JSObject* array = asObject(args.at(0));
-            int length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
+            unsigned length = array->get(exec, JSC::Identifier(exec, "length")).toUInt32(exec);
             void* tempValues;
-            if (!tryFastMalloc(length * sizeof(T)).getValue(tempValues)) {
+            if (!tryFastCalloc(length, sizeof(T)).getValue(tempValues)) {
                 throwError(exec, JSC::GeneralError);
                 return 0;
             }
             
             OwnFastMallocPtr<T> values(static_cast<T*>(tempValues));
-            for (int i = 0; i < length; ++i) {
+            for (unsigned i = 0; i < length; ++i) {
                 JSC::JSValue v = array->get(exec, i);
                 if (exec->hadException())
                     return 0;
@@ -78,7 +85,7 @@ namespace WebCore {
             return C::create(values.get(), length);
         }
         
-        unsigned size = static_cast<unsigned>(args.at(0).toInt32(exec));
+        unsigned size = args.at(0).toUInt32(exec);
         return C::create(size);
     }
 
index 3326d76..481c68f 100644 (file)
@@ -43,14 +43,16 @@ JSC::JSValue setWebGLArrayFromArray(JSC::ExecState* exec, T* webGLArray, JSC::Ar
     if (args.at(0).isObject()) {
         // void set(in sequence<long> array, [Optional] in unsigned long offset);
         JSC::JSObject* array = JSC::asObject(args.at(0));
-        unsigned offset = 0;
+        uint32_t offset = 0;
         if (args.size() == 2)
             offset = args.at(1).toInt32(exec);
-        int length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
-        if (offset + length > webGLArray->length())
+        uint32_t length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec);
+        if (offset > webGLArray->length() ||
+            offset + length > webGLArray->length() ||
+            offset + length < offset)
             setDOMException(exec, INDEX_SIZE_ERR);
         else {
-            for (int i = 0; i < length; i++) {
+            for (uint32_t i = 0; i < length; i++) {
                 JSC::JSValue v = array->get(exec, i);
                 if (exec->hadException())
                     return JSC::jsUndefined();
index 7db710f..f76fb1d 100644 (file)
@@ -53,6 +53,10 @@ static JSObject* constructCanvasByteArray(ExecState* exec, JSObject* constructor
 {
     JSWebGLByteArrayConstructor* jsConstructor = static_cast<JSWebGLByteArrayConstructor*>(constructor);
     RefPtr<WebGLByteArray> array = static_cast<WebGLByteArray*>(construct<WebGLByteArray, signed char>(exec, args).get());
+    if (!array.get()) {
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
     return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
 }
 
index 707fe56..e6375ac 100644 (file)
@@ -53,6 +53,10 @@ static JSObject* constructCanvasFloatArray(ExecState* exec, JSObject* constructo
 {
     JSWebGLFloatArrayConstructor* jsConstructor = static_cast<JSWebGLFloatArrayConstructor*>(constructor);
     RefPtr<WebGLFloatArray> array = static_cast<WebGLFloatArray*>(construct<WebGLFloatArray, float>(exec, args).get());
+    if (!array.get()) {
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
     return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
 }
 
index f2a0922..5b14803 100644 (file)
@@ -53,6 +53,10 @@ static JSObject* constructCanvasIntArray(ExecState* exec, JSObject* constructor,
 {
     JSWebGLIntArrayConstructor* jsConstructor = static_cast<JSWebGLIntArrayConstructor*>(constructor);
     RefPtr<WebGLIntArray> array = static_cast<WebGLIntArray*>(construct<WebGLIntArray, int>(exec, args).get());
+    if (!array.get()) {
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
     return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
 }
 
index 74bfe5c..a33779b 100644 (file)
@@ -54,6 +54,10 @@ static JSObject* constructCanvasShortArray(ExecState* exec, JSObject* constructo
 {
     JSWebGLShortArrayConstructor* jsConstructor = static_cast<JSWebGLShortArrayConstructor*>(constructor);
     RefPtr<WebGLShortArray> array = static_cast<WebGLShortArray*>(construct<WebGLShortArray, short>(exec, args).get());
+    if (!array.get()) {
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
     return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
 }
 
index d5597ce..dcb940e 100644 (file)
@@ -30,6 +30,7 @@
 #include "JSWebGLUnsignedByteArrayConstructor.h"
 
 #include "Document.h"
+#include "ExceptionCode.h"
 #include "WebGLUnsignedByteArray.h"
 #include "JSWebGLArrayBuffer.h"
 #include "JSWebGLArrayBufferConstructor.h"
@@ -53,6 +54,10 @@ static JSObject* constructCanvasUnsignedByteArray(ExecState* exec, JSObject* con
 {
     JSWebGLUnsignedByteArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedByteArrayConstructor*>(constructor);
     RefPtr<WebGLUnsignedByteArray> array = static_cast<WebGLUnsignedByteArray*>(construct<WebGLUnsignedByteArray, unsigned char>(exec, args).get());
+    if (!array.get()) {
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
     return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
 }
 
index 6fafa81..23fccce 100644 (file)
@@ -53,6 +53,10 @@ static JSObject* constructCanvasUnsignedIntArray(ExecState* exec, JSObject* cons
 {
     JSWebGLUnsignedIntArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedIntArrayConstructor*>(constructor);
     RefPtr<WebGLUnsignedIntArray> array = static_cast<WebGLUnsignedIntArray*>(construct<WebGLUnsignedIntArray, unsigned int>(exec, args).get());
+    if (!array.get()) {
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
     return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
 }
 
index deaeffd..d8c2cfb 100644 (file)
@@ -53,6 +53,10 @@ static JSObject* constructCanvasUnsignedShortArray(ExecState* exec, JSObject* co
 {
     JSWebGLUnsignedShortArrayConstructor* jsConstructor = static_cast<JSWebGLUnsignedShortArrayConstructor*>(constructor);
     RefPtr<WebGLUnsignedShortArray> array = static_cast<WebGLUnsignedShortArray*>(construct<WebGLUnsignedShortArray, unsigned short>(exec, args).get());
+    if (!array.get()) {
+        setDOMException(exec, INDEX_SIZE_ERR);
+        return 0;
+    }
     return asObject(toJS(exec, jsConstructor->globalObject(), array.get()));
 }
 
index 34020be..040cf54 100644 (file)
@@ -174,6 +174,53 @@ int toInt32(v8::Handle<v8::Value> value, bool& ok)
     return intValue->Value();
 }
     
+uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok)
+{
+    ok = true;
+
+    // FIXME: there is currently no Value::IsUint32(). This code does
+    // some contortions to avoid silently converting out-of-range
+    // values to uint32_t.
+
+    // Fast case.  The value is already a 32-bit positive integer.
+    if (value->IsInt32()) {
+        int32_t result = value->Int32Value();
+        if (result >= 0)
+            return result;
+    }
+
+    // Can the value be converted to a number?
+    v8::Local<v8::Number> numberObject = value->ToNumber();
+    if (numberObject.IsEmpty()) {
+        ok = false;
+        return 0;
+    }
+
+    // Does the value convert to nan or to an infinity?
+    double numberValue = numberObject->Value();
+    if (isnan(numberValue) || isinf(numberValue)) {
+        ok = false;
+        return 0;
+    }
+
+    // Can the value be converted to a 32-bit unsigned integer?
+    v8::Local<v8::Uint32> uintValue = value->ToUint32();
+    if (uintValue.IsEmpty()) {
+        ok = false;
+        return 0;
+    }
+
+    // FIXME: v8::Uint32::Value is not defined!
+    // http://code.google.com/p/v8/issues/detail?id=624
+    v8::Local<v8::Int32> intValue = value->ToInt32();
+    if (intValue.IsEmpty()) {
+        ok = false;
+        return 0;
+    }
+
+    return static_cast<uint32_t>(intValue->Value());
+}
+
 String toWebCoreString(const v8::Arguments& args, int index) {
     return v8ValueToWebCoreString(args[index]);
 }
index 0be0ebd..696cd1a 100644 (file)
@@ -108,6 +108,17 @@ namespace WebCore {
         return toInt32(value, ok);
     }
 
+    // Convert a value to a 32-bit unsigned integer.  The conversion fails if the
+    // value cannot be converted to an unsigned integer or converts to nan or to an infinity.
+    uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok);
+
+    // Convert a value to a 32-bit unsigned integer assuming the conversion cannot fail.
+    inline uint32_t toUInt32(v8::Handle<v8::Value> value)
+    {
+        bool ok;
+        return toUInt32(value, ok);
+    }
+
     inline float toFloat(v8::Local<v8::Value> value)
     {
         return static_cast<float>(value->NumberValue());
index 5b54563..db0c8c1 100644 (file)
@@ -72,7 +72,11 @@ v8::Handle<v8::Value> V8WebGLArrayBuffer::constructorCallback(const v8::Argument
         len = toInt32(args[0]);
     }
 
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len);
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(len, 1);
+    if (!buffer.get()) {
+        V8Proxy::setDOMException(INDEX_SIZE_ERR);
+        return v8::Undefined();
+    }
     // Transform the holder into a wrapper object for the array.
     V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::WEBGLARRAYBUFFER), buffer.get());
     return toV8(buffer.release(), args.Holder());
index beea8e6..de740ea 100644 (file)
@@ -41,7 +41,7 @@
 namespace WebCore {
 
 // Template function used by the WebGLArray*Constructor callbacks.
-template<class ArrayClass>
+template<class ArrayClass, class ElementType>
 v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
                                           int classIndex)
 {
@@ -71,31 +71,26 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
 
     // See whether the first argument is a WebGLArrayBuffer.
     if (V8WebGLArrayBuffer::HasInstance(args[0])) {
-        if (argLen > 3)
-            return throwError("Wrong number of arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
-
         WebGLArrayBuffer* buf = V8WebGLArrayBuffer::toNative(args[0]->ToObject());
-        if (buf == NULL)
+        if (!buf)
             return throwError("Could not convert argument 0 to a WebGLArrayBuffer");
         bool ok;
-        int offset = 0;
+        uint32_t offset = 0;
         if (argLen > 1) {
-            offset = toInt32(args[1], ok);
+            offset = toUInt32(args[1], ok);
             if (!ok)
-                return throwError("Could not convert argument 1 to an integer");
+                return throwError("Could not convert argument 1 to a number");
         }
-        int length = buf->byteLength() - offset;
+        uint32_t length = (buf->byteLength() - offset) / sizeof(ElementType);
         if (argLen > 2) {
-            length = toInt32(args[2], ok);
+            length = toUInt32(args[2], ok);
             if (!ok)
-                return throwError("Could not convert argument 2 to an integer");
+                return throwError("Could not convert argument 2 to a number");
         }
-        if (length < 0)
-            return throwError("Length / offset out of range");
 
         RefPtr<ArrayClass> array = ArrayClass::create(buf, offset, length);
-        if (array == NULL)
-            return throwError("Invalid arguments to new WebGL<T>Array(WebGLArrayBuffer, int, int)");
+        if (!array)
+            return throwError("Out-of-range offset and/or length");
         // Transform the holder into a wrapper object for the array.
         V8DOMWrapper::setDOMWrapper(args.Holder(), classIndex, array.get());
         V8DOMWrapper::setIndexedPropertiesToExternalArray(args.Holder(),
@@ -105,26 +100,28 @@ v8::Handle<v8::Value> constructWebGLArray(const v8::Arguments& args,
         return toV8(array.release(), args.Holder());
     }
 
-    int len = 0;
+    uint32_t len = 0;
     v8::Handle<v8::Object> srcArray;
-    if (argLen != 1)
-        return throwError("Wrong number of arguments to new WebGL<T>Array(int / array)");
 
     if (args[0]->IsInt32()) {
-        len = toInt32(args[0]);
+        len = toUInt32(args[0]);
     } else if (args[0]->IsObject()) {
         srcArray = args[0]->ToObject();
         if (srcArray.IsEmpty())
-            return throwError("Could not convert argument 0 to an object");
-        len = toInt32(srcArray->Get(v8::String::New("length")));
+            return throwError("Could not convert argument 0 to an array");
+        len = toUInt32(srcArray->Get(v8::String::New("length")));
     } else
-        return throwError("Could not convert argument 0 to either an int32 or an object");
+        return throwError("Could not convert argument 0 to either a number or an array");
 
     RefPtr<ArrayClass> array = ArrayClass::create(len);
+    if (!array.get()) {
+        V8Proxy::setDOMException(INDEX_SIZE_ERR);
+        return v8::Undefined();
+    }
     if (!srcArray.IsEmpty()) {
         // Need to copy the incoming array into the newly created WebGLArray.
-        for (int i = 0; i < len; i++) {
-            v8::Local<v8::Value> val = srcArray->Get(v8::Integer::New(i));
+        for (unsigned i = 0; i < len; i++) {
+            v8::Local<v8::Value> val = srcArray->Get(v8::Integer::NewFromUnsigned(i));
             array->set(i, val->NumberValue());
         }
     }
@@ -147,7 +144,7 @@ v8::Handle<v8::Value> getWebGLArrayElement(const v8::Arguments& args,
         return notHandledByInterceptor();
     }
     bool ok;
-    uint32_t index = toInt32(args[0], ok);
+    uint32_t index = toUInt32(args[0], ok);
     if (!ok) {
         V8Proxy::setDOMException(SYNTAX_ERR);
         return notHandledByInterceptor();
@@ -169,13 +166,16 @@ v8::Handle<v8::Value> setWebGLArrayFromArray(T* webGLArray, const v8::Arguments&
         v8::Local<v8::Object> array = args[0]->ToObject();
         uint32_t offset = 0;
         if (args.Length() == 2)
-            offset = toInt32(args[1]);
-        uint32_t length = toInt32(array->Get(v8::String::New("length")));
-        if (offset + length > webGLArray->length())
+            offset = toUInt32(args[1]);
+        uint32_t length = toUInt32(array->Get(v8::String::New("length")));
+        if (offset > webGLArray->length() ||
+            offset + length > webGLArray->length() ||
+            offset + length < offset)
+            // Out of range offset or overflow
             V8Proxy::setDOMException(INDEX_SIZE_ERR);
         else
             for (uint32_t i = 0; i < length; i++)
-                webGLArray->set(offset + i, array->Get(v8::Integer::New(i))->NumberValue());
+                webGLArray->set(offset + i, array->Get(v8::Integer::NewFromUnsigned(i))->NumberValue());
     }
 
     return v8::Undefined();
@@ -192,9 +192,10 @@ v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
 
     CPlusPlusArrayType* array = JavaScriptWrapperArrayType::toNative(args.Holder());
 
+    // FIXME: change to IsUInt32() when available
     if (args.Length() == 2 && args[0]->IsInt32()) {
         // void set(in unsigned long index, in {long|float} value);
-        uint32_t index = toInt32(args[0]);
+        uint32_t index = toUInt32(args[0]);
         array->set(index, args[1]->NumberValue());
         return v8::Undefined();
     }
@@ -204,7 +205,7 @@ v8::Handle<v8::Value> setWebGLArray(const v8::Arguments& args,
         CPlusPlusArrayType* src = JavaScriptWrapperArrayType::toNative(args[0]->ToObject());
         uint32_t offset = 0;
         if (args.Length() == 2)
-            offset = toInt32(args[1]);
+            offset = toUInt32(args[1]);
         ExceptionCode ec = 0;
         array->set(src, offset, ec);
         V8Proxy::setDOMException(ec);
index dd6163a..3544081 100644 (file)
@@ -47,7 +47,7 @@ v8::Handle<v8::Value> V8WebGLByteArray::constructorCallback(const v8::Arguments&
 {
     INC_STATS("DOM.WebGLByteArray.Contructor");
 
-    return constructWebGLArray<WebGLByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLBYTEARRAY));
+    return constructWebGLArray<WebGLByteArray, signed char>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLBYTEARRAY));
 }
 
 v8::Handle<v8::Value> V8WebGLByteArray::getCallback(const v8::Arguments& args)
index 3fb8865..3c49c31 100644 (file)
@@ -47,7 +47,7 @@ v8::Handle<v8::Value> V8WebGLFloatArray::constructorCallback(const v8::Arguments
 {
     INC_STATS("DOM.WebGLFloatArray.Contructor");
 
-    return constructWebGLArray<WebGLFloatArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLFLOATARRAY));
+    return constructWebGLArray<WebGLFloatArray, float>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLFLOATARRAY));
 }
 
 v8::Handle<v8::Value> V8WebGLFloatArray::getCallback(const v8::Arguments& args)
index 0141a0b..87a3ce0 100644 (file)
@@ -47,7 +47,7 @@ v8::Handle<v8::Value> V8WebGLIntArray::constructorCallback(const v8::Arguments&
 {
     INC_STATS("DOM.WebGLIntArray.Contructor");
 
-    return constructWebGLArray<WebGLIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLINTARRAY));
+    return constructWebGLArray<WebGLIntArray, int>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLINTARRAY));
 }
 
 v8::Handle<v8::Value> V8WebGLIntArray::getCallback(const v8::Arguments& args)
index 5a2408e..034450c 100644 (file)
@@ -47,7 +47,7 @@ v8::Handle<v8::Value> V8WebGLShortArray::constructorCallback(const v8::Arguments
 {
     INC_STATS("DOM.WebGLShortArray.Contructor");
 
-    return constructWebGLArray<WebGLShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLSHORTARRAY));
+    return constructWebGLArray<WebGLShortArray, short>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLSHORTARRAY));
 }
 
 v8::Handle<v8::Value> V8WebGLShortArray::getCallback(const v8::Arguments& args)
index 5a30ace..7246287 100644 (file)
@@ -47,7 +47,7 @@ v8::Handle<v8::Value> V8WebGLUnsignedByteArray::constructorCallback(const v8::Ar
 {
     INC_STATS("DOM.WebGLUnsignedByteArray.Contructor");
 
-    return constructWebGLArray<WebGLUnsignedByteArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY));
+    return constructWebGLArray<WebGLUnsignedByteArray, unsigned char>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDBYTEARRAY));
 }
 
 v8::Handle<v8::Value> V8WebGLUnsignedByteArray::getCallback(const v8::Arguments& args)
index cefc60e..fc0a514 100644 (file)
@@ -47,7 +47,7 @@ v8::Handle<v8::Value> V8WebGLUnsignedIntArray::constructorCallback(const v8::Arg
 {
     INC_STATS("DOM.WebGLUnsignedIntArray.Contructor");
 
-    return constructWebGLArray<WebGLUnsignedIntArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDINTARRAY));
+    return constructWebGLArray<WebGLUnsignedIntArray, unsigned int>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDINTARRAY));
 }
 
 v8::Handle<v8::Value> V8WebGLUnsignedIntArray::getCallback(const v8::Arguments& args)
index 56e34b8..8cdc093 100644 (file)
@@ -47,7 +47,7 @@ v8::Handle<v8::Value> V8WebGLUnsignedShortArray::constructorCallback(const v8::A
 {
     INC_STATS("DOM.WebGLUnsignedShortArray.Contructor");
 
-    return constructWebGLArray<WebGLUnsignedShortArray>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY));
+    return constructWebGLArray<WebGLUnsignedShortArray, unsigned short>(args, V8ClassIndex::ToInt(V8ClassIndex::WEBGLUNSIGNEDSHORTARRAY));
 }
 
 v8::Handle<v8::Value> V8WebGLUnsignedShortArray::getCallback(const v8::Arguments& args)
index c5a712d..49996d3 100644 (file)
@@ -46,7 +46,10 @@ WebGLArray::~WebGLArray()
 
 void WebGLArray::setImpl(WebGLArray* array, unsigned byteOffset, ExceptionCode& ec)
 {
-    if (byteOffset + array->byteLength() > byteLength()) {
+    if (byteOffset > byteLength() ||
+        byteOffset + array->byteLength() > byteLength() ||
+        byteOffset + array->byteLength() < byteOffset) {
+        // Out of range offset or overflow
         ec = INDEX_SIZE_ERR;
         return;
     }
index 11065cc..255b56b 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef WebGLArray_h
 #define WebGLArray_h
 
+#include <algorithm>
 #include "ExceptionCode.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -67,6 +68,35 @@ class WebGLArray : public RefCounted<WebGLArray> {
 
     void setImpl(WebGLArray* array, unsigned byteOffset, ExceptionCode& ec);
 
+    // Helper to verify that a given sub-range of an ArrayBuffer is
+    // within range.
+    template <typename T>
+    static bool verifySubRange(PassRefPtr<WebGLArrayBuffer> buffer,
+                               unsigned byteOffset,
+                               unsigned numElements)
+    {
+        if (!buffer)
+            return false;
+        if (sizeof(T) > 1 && byteOffset % sizeof(T))
+            return false;
+        if (byteOffset > buffer->byteLength())
+            return false;
+        unsigned remainingElements = (buffer->byteLength() - byteOffset) / sizeof(T);
+        if (numElements > remainingElements)
+            return false;
+        return true;
+    }
+
+    template <typename T>
+    static void clampOffsetAndNumElements(PassRefPtr<WebGLArrayBuffer> buffer,
+                                          unsigned *byteOffset,
+                                          unsigned *numElements)
+    {
+        *byteOffset = std::min(buffer->byteLength(), *byteOffset);
+        unsigned remainingElements = (buffer->byteLength() - *byteOffset) / sizeof(T);
+        *numElements = std::min(remainingElements, *numElements);
+    }
+
     // This is the address of the WebGLArrayBuffer's storage, plus the byte offset.
     void* m_baseAddress;
 
index c565691..7d3cd33 100644 (file)
 
 namespace WebCore {
 
-PassRefPtr<WebGLArrayBuffer> WebGLArrayBuffer::create(unsigned sizeInBytes)
+PassRefPtr<WebGLArrayBuffer> WebGLArrayBuffer::create(unsigned numElements, unsigned elementByteSize)
 {
-    return adoptRef(new WebGLArrayBuffer(sizeInBytes));
+    void* data = tryAllocate(numElements, elementByteSize);
+    if (!data)
+        return 0;
+    return adoptRef(new WebGLArrayBuffer(data, numElements * elementByteSize));
 }
 
 PassRefPtr<WebGLArrayBuffer> WebGLArrayBuffer::create(WebGLArrayBuffer* other)
 {
-    RefPtr<WebGLArrayBuffer> buffer = adoptRef(new WebGLArrayBuffer(other->byteLength()));
+    void* data = tryAllocate(other->byteLength(), 1);
+    if (!data)
+        return 0;
+    RefPtr<WebGLArrayBuffer> buffer = adoptRef(new WebGLArrayBuffer(data, other->byteLength()));
     memcpy(buffer->data(), other->data(), other->byteLength());
     return buffer.release();
 }
 
-WebGLArrayBuffer::WebGLArrayBuffer(unsigned sizeInBytes) {
-    m_sizeInBytes = sizeInBytes;
-    m_data = WTF::fastZeroedMalloc(sizeInBytes);
+WebGLArrayBuffer::WebGLArrayBuffer(void* data, unsigned sizeInBytes)
+    : m_sizeInBytes(sizeInBytes)
+    , m_data(data) {
 }
 
 void* WebGLArrayBuffer::data() {
@@ -66,6 +72,19 @@ WebGLArrayBuffer::~WebGLArrayBuffer() {
     WTF::fastFree(m_data);
 }
 
+void* WebGLArrayBuffer::tryAllocate(unsigned numElements, unsigned elementByteSize) {
+    void* result;
+    // Do not allow 32-bit overflow of the total size
+    if (numElements) {
+        unsigned totalSize = numElements * elementByteSize;
+        if (totalSize / numElements != elementByteSize)
+            return 0;
+    }
+    if (WTF::tryFastCalloc(numElements, elementByteSize).getValue(result))
+        return result;
+    return 0;
+}
+
 }
 
 #endif // ENABLE(3D_CANVAS)
index a076e16..59e0ddd 100644 (file)
@@ -33,7 +33,7 @@ namespace WebCore {
 
 class WebGLArrayBuffer : public RefCounted<WebGLArrayBuffer> {
   public:
-    static PassRefPtr<WebGLArrayBuffer> create(unsigned sizeInBytes);
+    static PassRefPtr<WebGLArrayBuffer> create(unsigned numElements, unsigned elementByteSize);
     static PassRefPtr<WebGLArrayBuffer> create(WebGLArrayBuffer*);
 
     void* data();
@@ -43,7 +43,9 @@ class WebGLArrayBuffer : public RefCounted<WebGLArrayBuffer> {
     ~WebGLArrayBuffer();
 
   private:
-    WebGLArrayBuffer(unsigned sizeInBytes);
+    WebGLArrayBuffer(void* data, unsigned sizeInBytes);
+    WebGLArrayBuffer(unsigned numElements, unsigned elementByteSize);
+    static void* tryAllocate(unsigned numElements, unsigned elementByteSize);
     unsigned m_sizeInBytes;
     void* m_data;
 };
index 1c2849b..0915697 100644 (file)
@@ -35,7 +35,7 @@ namespace WebCore {
 
 PassRefPtr<WebGLByteArray> WebGLByteArray::create(unsigned length)
 {
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length * sizeof(signed char));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length, sizeof(signed char));
     return create(buffer, 0, length);
 }
 
@@ -47,19 +47,16 @@ PassRefPtr<WebGLByteArray> WebGLByteArray::create(signed char* array, unsigned l
     return a;
 }
 
-PassRefPtr<WebGLByteArray> WebGLByteArray::create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length)
+PassRefPtr<WebGLByteArray> WebGLByteArray::create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length)
 {
-    if (buffer) {
-        // Check to make sure we are talking about a valid region of
-        // the given WebGLArrayBuffer's storage.
-        if ((byteOffset + (length * sizeof(signed char))) > buffer->byteLength())
-            return NULL;
-    }
+    RefPtr<WebGLArrayBuffer> buf(buffer);
+    if (!verifySubRange<signed char>(buf, byteOffset, length))
+        return 0;
 
-    return adoptRef(new WebGLByteArray(buffer, byteOffset, length));
+    return adoptRef(new WebGLByteArray(buf, byteOffset, length));
 }
 
-WebGLByteArray::WebGLByteArray(PassRefPtr<WebGLArrayBuffer> buffer, int offset, unsigned length)
+WebGLByteArray::WebGLByteArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned offset, unsigned length)
     : WebGLArray(buffer, offset)
     , m_size(length)
 {
@@ -74,14 +71,9 @@ unsigned WebGLByteArray::byteLength() const {
 }
 
 PassRefPtr<WebGLArray> WebGLByteArray::slice(unsigned offset, unsigned length) {
-    // Check to make sure the specified region is within the bounds of
-    // the WebGLArrayBuffer.
-    unsigned startByte = m_byteOffset + offset * sizeof(signed char);
-    unsigned limitByte = startByte + length * sizeof(signed char);
-    unsigned bufferLength = buffer()->byteLength();
-    if (startByte >= bufferLength || limitByte > bufferLength)
-        return 0;
-    return create(buffer(), startByte, length);
+    unsigned fullOffset = m_byteOffset + offset * sizeof(signed char);
+    clampOffsetAndNumElements<signed char>(buffer().get(), &fullOffset, &length);
+    return create(buffer(), fullOffset, length);
 }
 
 void WebGLByteArray::set(WebGLByteArray* array, unsigned offset, ExceptionCode& ec) {
index c517c03..5035127 100644 (file)
@@ -43,7 +43,7 @@ class WebGLByteArray : public WebGLArray {
 
     static PassRefPtr<WebGLByteArray> create(unsigned length);
     static PassRefPtr<WebGLByteArray> create(signed char* array, unsigned length);
-    static PassRefPtr<WebGLByteArray> create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    static PassRefPtr<WebGLByteArray> create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
 
     char* data() { return static_cast<char*>(baseAddress()); }
 
@@ -90,7 +90,7 @@ class WebGLByteArray : public WebGLArray {
 
   private:
     WebGLByteArray(PassRefPtr<WebGLArrayBuffer> buffer,
-                   int offset,
+                   unsigned offset,
                    unsigned length);
     unsigned m_size;
 };
index 6192898..a3dcc93 100644 (file)
@@ -34,7 +34,7 @@ namespace WebCore {
 
 PassRefPtr<WebGLFloatArray> WebGLFloatArray::create(unsigned length)
 {
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length * sizeof(float));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length, sizeof(float));
     return create(buffer, 0, length);
 }
 
@@ -46,22 +46,16 @@ PassRefPtr<WebGLFloatArray> WebGLFloatArray::create(float* array, unsigned lengt
     return a;
 }
 
-PassRefPtr<WebGLFloatArray> WebGLFloatArray::create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length)
+PassRefPtr<WebGLFloatArray> WebGLFloatArray::create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length)
 {
-    // Make sure the offset results in valid alignment.
-    if ((byteOffset % sizeof(float)) != 0)
-        return NULL;
+    RefPtr<WebGLArrayBuffer> buf(buffer);
+    if (!verifySubRange<float>(buf, byteOffset, length))
+        return 0;
 
-    if (buffer) {
-        // Check to make sure we are talking about a valid region of
-        // the given WebGLArrayBuffer's storage.
-        if ((byteOffset + (length * sizeof(float))) > buffer->byteLength())
-            return NULL;
-    }
-    return adoptRef(new WebGLFloatArray(buffer, byteOffset, length));
+    return adoptRef(new WebGLFloatArray(buf, byteOffset, length));
 }
 
-WebGLFloatArray::WebGLFloatArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length)
+WebGLFloatArray::WebGLFloatArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length)
         : WebGLArray(buffer, byteOffset)
         , m_size(length)
 {
@@ -76,14 +70,9 @@ unsigned WebGLFloatArray::byteLength() const {
 }
 
 PassRefPtr<WebGLArray> WebGLFloatArray::slice(unsigned offset, unsigned length) {
-    // Check to make sure the specified region is within the bounds of
-    // the WebGLArrayBuffer.
-    unsigned startByte = m_byteOffset + offset * sizeof(float);
-    unsigned limitByte = startByte + length * sizeof(float);
-    unsigned bufferLength = buffer()->byteLength();
-    if (startByte >= bufferLength || limitByte > bufferLength)
-        return 0;
-    return create(buffer(), startByte, length);
+    unsigned fullOffset = m_byteOffset + offset * sizeof(float);
+    clampOffsetAndNumElements<float>(buffer(), &fullOffset, &length);
+    return create(buffer(), fullOffset, length);
 }
 
 void WebGLFloatArray::set(WebGLFloatArray* array, unsigned offset, ExceptionCode& ec) {
index 4607962..33ab12b 100644 (file)
@@ -40,7 +40,7 @@ class WebGLFloatArray : public WebGLArray {
 
     static PassRefPtr<WebGLFloatArray> create(unsigned length);
     static PassRefPtr<WebGLFloatArray> create(float* array, unsigned length);
-    static PassRefPtr<WebGLFloatArray> create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    static PassRefPtr<WebGLFloatArray> create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
 
     float* data() { return static_cast<float*>(baseAddress()); }
 
@@ -86,7 +86,7 @@ class WebGLFloatArray : public WebGLArray {
     void set(WebGLFloatArray* array, unsigned offset, ExceptionCode& ec);
 
   private:
-    WebGLFloatArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    WebGLFloatArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
     unsigned m_size;
 };
 
index 4617010..3bfce76 100644 (file)
@@ -35,7 +35,7 @@ namespace WebCore {
 
 PassRefPtr<WebGLIntArray> WebGLIntArray::create(unsigned length)
 {
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length * sizeof(int));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length, sizeof(int));
     return create(buffer, 0, length);
 }
 
@@ -48,24 +48,17 @@ PassRefPtr<WebGLIntArray> WebGLIntArray::create(int* array, unsigned length)
 }
 
 PassRefPtr<WebGLIntArray> WebGLIntArray::create(PassRefPtr<WebGLArrayBuffer> buffer,
-                                                int byteOffset,
+                                                unsigned byteOffset,
                                                 unsigned length)
 {
-    // Make sure the offset results in valid alignment.
-    if ((byteOffset % sizeof(int)) != 0)
-        return NULL;
-
-    if (buffer) {
-        // Check to make sure we are talking about a valid region of
-        // the given WebGLArrayBuffer's storage.
-        if ((byteOffset + (length * sizeof(int))) > buffer->byteLength())
-            return NULL;
-    }
+    RefPtr<WebGLArrayBuffer> buf(buffer);
+    if (!verifySubRange<int>(buf, byteOffset, length))
+        return 0;
 
-    return adoptRef(new WebGLIntArray(buffer, byteOffset, length));
+    return adoptRef(new WebGLIntArray(buf, byteOffset, length));
 }
 
-WebGLIntArray::WebGLIntArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length)
+WebGLIntArray::WebGLIntArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length)
         : WebGLArray(buffer, byteOffset)
         , m_size(length)
 {
@@ -80,14 +73,9 @@ unsigned WebGLIntArray::byteLength() const {
 }
 
 PassRefPtr<WebGLArray> WebGLIntArray::slice(unsigned offset, unsigned length) {
-    // Check to make sure the specified region is within the bounds of
-    // the WebGLArrayBuffer.
-    unsigned startByte = m_byteOffset + offset * sizeof(int);
-    unsigned limitByte = startByte + length * sizeof(int);
-    unsigned bufferLength = buffer()->byteLength();
-    if (startByte >= bufferLength || limitByte > bufferLength)
-        return 0;
-    return create(buffer(), startByte, length);
+    unsigned fullOffset = m_byteOffset + offset * sizeof(int);
+    clampOffsetAndNumElements<int>(buffer(), &fullOffset, &length);
+    return create(buffer(), fullOffset, length);
 }
 
 void WebGLIntArray::set(WebGLIntArray* array, unsigned offset, ExceptionCode& ec) {
index 25108ac..af661c8 100644 (file)
@@ -41,7 +41,7 @@ class WebGLIntArray : public WebGLArray {
 
     static PassRefPtr<WebGLIntArray> create(unsigned length);
     static PassRefPtr<WebGLIntArray> create(int* array, unsigned length);
-    static PassRefPtr<WebGLIntArray> create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    static PassRefPtr<WebGLIntArray> create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
 
     int* data() { return static_cast<int*>(baseAddress()); }
 
@@ -87,7 +87,7 @@ class WebGLIntArray : public WebGLArray {
 
   private:
     WebGLIntArray(PassRefPtr<WebGLArrayBuffer> buffer,
-                  int byteOffset,
+                  unsigned byteOffset,
                   unsigned length);
     unsigned m_size;
 };
index f96a290..56d84c6 100644 (file)
@@ -34,7 +34,7 @@ namespace WebCore {
 
 PassRefPtr<WebGLShortArray> WebGLShortArray::create(unsigned length)
 {
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length * sizeof(short));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length, sizeof(short));
     return create(buffer, 0, length);
 }
 
@@ -47,24 +47,17 @@ PassRefPtr<WebGLShortArray> WebGLShortArray::create(short* array, unsigned lengt
 }
 
 PassRefPtr<WebGLShortArray> WebGLShortArray::create(PassRefPtr<WebGLArrayBuffer> buffer,
-                                                    int byteOffset,
+                                                    unsigned byteOffset,
                                                     unsigned length)
 {
-    // Make sure the offset results in valid alignment.
-    if ((byteOffset % sizeof(short)) != 0)
-        return NULL;
-
-    if (buffer) {
-        // Check to make sure we are talking about a valid region of
-        // the given WebGLArrayBuffer's storage.
-        if ((byteOffset + (length * sizeof(short))) > buffer->byteLength())
-            return NULL;
-    }
+    RefPtr<WebGLArrayBuffer> buf(buffer);
+    if (!verifySubRange<short>(buf, byteOffset, length))
+        return 0;
 
-    return adoptRef(new WebGLShortArray(buffer, byteOffset, length));
+    return adoptRef(new WebGLShortArray(buf, byteOffset, length));
 }
 
-WebGLShortArray::WebGLShortArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length)
+WebGLShortArray::WebGLShortArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length)
         : WebGLArray(buffer, byteOffset)
         , m_size(length)
 {
@@ -79,14 +72,9 @@ unsigned WebGLShortArray::byteLength() const {
 }
 
 PassRefPtr<WebGLArray> WebGLShortArray::slice(unsigned offset, unsigned length) {
-    // Check to make sure the specified region is within the bounds of
-    // the WebGLArrayBuffer.
-    unsigned startByte = m_byteOffset + offset * sizeof(short);
-    unsigned limitByte = startByte + length * sizeof(short);
-    unsigned bufferLength = buffer()->byteLength();
-    if (startByte >= bufferLength || limitByte > bufferLength)
-        return 0;
-    return create(buffer(), startByte, length);
+    unsigned fullOffset = m_byteOffset + offset * sizeof(short);
+    clampOffsetAndNumElements<short>(buffer(), &fullOffset, &length);
+    return create(buffer(), fullOffset, length);
 }
 
 void WebGLShortArray::set(WebGLShortArray* array, unsigned offset, ExceptionCode& ec) {
index 70c66ca..7544171 100644 (file)
@@ -40,7 +40,7 @@ class WebGLShortArray : public WebGLArray {
 
     static PassRefPtr<WebGLShortArray> create(unsigned length);
     static PassRefPtr<WebGLShortArray> create(short* array, unsigned length);
-    static PassRefPtr<WebGLShortArray> create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    static PassRefPtr<WebGLShortArray> create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
 
     short* data() { return static_cast<short*>(baseAddress()); }
 
@@ -85,7 +85,7 @@ class WebGLShortArray : public WebGLArray {
     void set(WebGLShortArray* array, unsigned offset, ExceptionCode& ec);
 
   private:
-    WebGLShortArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    WebGLShortArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
     unsigned m_size;
 };
 
index 3fd1b50..b7b6ab7 100644 (file)
@@ -35,7 +35,7 @@ namespace WebCore {
 
 PassRefPtr<WebGLUnsignedByteArray> WebGLUnsignedByteArray::create(unsigned length)
 {
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length * sizeof(unsigned char));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length, sizeof(unsigned char));
     return create(buffer, 0, length);
 }
 
@@ -48,20 +48,17 @@ PassRefPtr<WebGLUnsignedByteArray> WebGLUnsignedByteArray::create(unsigned char*
 }
 
 PassRefPtr<WebGLUnsignedByteArray> WebGLUnsignedByteArray::create(PassRefPtr<WebGLArrayBuffer> buffer,
-                                                                  int byteOffset,
+                                                                  unsigned byteOffset,
                                                                   unsigned length)
 {
-    if (buffer) {
-        // Check to make sure we are talking about a valid region of
-        // the given WebGLArrayBuffer's storage.
-        if ((byteOffset + (length * sizeof(unsigned char))) > buffer->byteLength())
-            return NULL;
-    }
+    RefPtr<WebGLArrayBuffer> buf(buffer);
+    if (!verifySubRange<unsigned char>(buf, byteOffset, length))
+        return 0;
 
-    return adoptRef(new WebGLUnsignedByteArray(buffer, byteOffset, length));
+    return adoptRef(new WebGLUnsignedByteArray(buf, byteOffset, length));
 }
 
-WebGLUnsignedByteArray::WebGLUnsignedByteArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length)
+WebGLUnsignedByteArray::WebGLUnsignedByteArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length)
         : WebGLArray(buffer, byteOffset)
         , m_size(length)
 {
@@ -76,14 +73,9 @@ unsigned WebGLUnsignedByteArray::byteLength() const {
 }
 
 PassRefPtr<WebGLArray> WebGLUnsignedByteArray::slice(unsigned offset, unsigned length) {
-    // Check to make sure the specified region is within the bounds of
-    // the WebGLArrayBuffer.
-    unsigned startByte = m_byteOffset + offset * sizeof(unsigned char);
-    unsigned limitByte = startByte + length * sizeof(unsigned char);
-    unsigned bufferLength = buffer()->byteLength();
-    if (startByte >= bufferLength || limitByte > bufferLength)
-        return 0;
-    return create(buffer(), startByte, length);
+    unsigned fullOffset = m_byteOffset + offset * sizeof(unsigned char);
+    clampOffsetAndNumElements<unsigned char>(buffer(), &fullOffset, &length);
+    return create(buffer(), fullOffset, length);
 }
 
 void WebGLUnsignedByteArray::set(WebGLUnsignedByteArray* array, unsigned offset, ExceptionCode& ec) {
index 6909de5..c2b596a 100644 (file)
@@ -41,7 +41,7 @@ class WebGLUnsignedByteArray : public WebGLArray {
 
     static PassRefPtr<WebGLUnsignedByteArray> create(unsigned length);
     static PassRefPtr<WebGLUnsignedByteArray> create(unsigned char* array, unsigned length);
-    static PassRefPtr<WebGLUnsignedByteArray> create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    static PassRefPtr<WebGLUnsignedByteArray> create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
 
     unsigned char* data() { return static_cast<unsigned char*>(baseAddress()); }
 
@@ -86,7 +86,7 @@ class WebGLUnsignedByteArray : public WebGLArray {
     void set(WebGLUnsignedByteArray* array, unsigned offset, ExceptionCode& ec);
 
   private:
-    WebGLUnsignedByteArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    WebGLUnsignedByteArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
     unsigned m_size;
 };
 
index 97910f9..8a2f561 100644 (file)
@@ -35,7 +35,7 @@ namespace WebCore {
 
 PassRefPtr<WebGLUnsignedIntArray> WebGLUnsignedIntArray::create(unsigned length)
 {
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length * sizeof(unsigned int));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length, sizeof(unsigned int));
     return create(buffer, 0, length);
 }
 
@@ -48,25 +48,17 @@ PassRefPtr<WebGLUnsignedIntArray> WebGLUnsignedIntArray::create(unsigned int* ar
 }
 
 PassRefPtr<WebGLUnsignedIntArray> WebGLUnsignedIntArray::create(PassRefPtr<WebGLArrayBuffer> buffer,
-                                                                int byteOffset,
+                                                                unsigned byteOffset,
                                                                 unsigned length)
 {
-    // Make sure the offset results in valid alignment.
-    if ((byteOffset % sizeof(unsigned int)) != 0) {
-        return NULL;
-    }
-
-    if (buffer) {
-        // Check to make sure we are talking about a valid region of
-        // the given WebGLArrayBuffer's storage.
-        if ((byteOffset + (length * sizeof(unsigned int))) > buffer->byteLength())
-            return NULL;
-    }
+    RefPtr<WebGLArrayBuffer> buf(buffer);
+    if (!verifySubRange<unsigned int>(buf, byteOffset, length))
+        return 0;
 
-    return adoptRef(new WebGLUnsignedIntArray(buffer, byteOffset, length));
+    return adoptRef(new WebGLUnsignedIntArray(buf, byteOffset, length));
 }
 
-WebGLUnsignedIntArray::WebGLUnsignedIntArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length)
+WebGLUnsignedIntArray::WebGLUnsignedIntArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length)
         : WebGLArray(buffer, byteOffset)
         , m_size(length)
 {
@@ -81,14 +73,9 @@ unsigned WebGLUnsignedIntArray::byteLength() const {
 }
 
 PassRefPtr<WebGLArray> WebGLUnsignedIntArray::slice(unsigned offset, unsigned length) {
-    // Check to make sure the specified region is within the bounds of
-    // the WebGLArrayBuffer.
-    unsigned startByte = m_byteOffset + offset * sizeof(unsigned int);
-    unsigned limitByte = startByte + length * sizeof(unsigned int);
-    unsigned bufferLength = buffer()->byteLength();
-    if (startByte >= bufferLength || limitByte > bufferLength)
-        return 0;
-    return create(buffer(), startByte, length);
+    unsigned fullOffset = m_byteOffset + offset * sizeof(unsigned int);
+    clampOffsetAndNumElements<unsigned int>(buffer(), &fullOffset, &length);
+    return create(buffer(), fullOffset, length);
 }
 
 void WebGLUnsignedIntArray::set(WebGLUnsignedIntArray* array, unsigned offset, ExceptionCode& ec) {
index b0d9b65..8abf05b 100644 (file)
@@ -41,7 +41,7 @@ class WebGLUnsignedIntArray : public WebGLArray {
 
     static PassRefPtr<WebGLUnsignedIntArray> create(unsigned length);
     static PassRefPtr<WebGLUnsignedIntArray> create(unsigned int* array, unsigned length);
-    static PassRefPtr<WebGLUnsignedIntArray> create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    static PassRefPtr<WebGLUnsignedIntArray> create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
 
     unsigned int* data() { return static_cast<unsigned int*>(baseAddress()); }
 
@@ -86,7 +86,7 @@ class WebGLUnsignedIntArray : public WebGLArray {
     void set(WebGLUnsignedIntArray* array, unsigned offset, ExceptionCode& ec);
 
   private:
-    WebGLUnsignedIntArray(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    WebGLUnsignedIntArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
     unsigned m_size;
 };
 
index 86fae8c..a960cef 100644 (file)
@@ -35,7 +35,7 @@ namespace WebCore {
 
 PassRefPtr<WebGLUnsignedShortArray> WebGLUnsignedShortArray::create(unsigned length)
 {
-    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length * sizeof(unsigned short));
+    RefPtr<WebGLArrayBuffer> buffer = WebGLArrayBuffer::create(length, sizeof(unsigned short));
     return create(buffer, 0, length);
 }
 
@@ -48,26 +48,18 @@ PassRefPtr<WebGLUnsignedShortArray> WebGLUnsignedShortArray::create(unsigned sho
 }
 
 PassRefPtr<WebGLUnsignedShortArray> WebGLUnsignedShortArray::create(PassRefPtr<WebGLArrayBuffer> buffer,
-                                                                    int byteOffset,
+                                                                    unsigned byteOffset,
                                                                     unsigned length)
 {
-    // Make sure the offset results in valid alignment.
-    if ((byteOffset % sizeof(unsigned short)) != 0) {
-        return NULL;
-    }
-
-    if (buffer) {
-        // Check to make sure we are talking about a valid region of
-        // the given WebGLArrayBuffer's storage.
-        if ((byteOffset + (length * sizeof(unsigned short))) > buffer->byteLength()) 
-            return NULL;
-    }
+    RefPtr<WebGLArrayBuffer> buf(buffer);
+    if (!verifySubRange<unsigned short>(buf, byteOffset, length))
+        return 0;
 
-    return adoptRef(new WebGLUnsignedShortArray(buffer, byteOffset, length));
+    return adoptRef(new WebGLUnsignedShortArray(buf, byteOffset, length));
 }
 
 WebGLUnsignedShortArray::WebGLUnsignedShortArray(PassRefPtr<WebGLArrayBuffer> buffer,
-                                                 int byteOffset,
+                                                 unsigned byteOffset,
                                                  unsigned length)
         : WebGLArray(buffer, byteOffset)
         , m_size(length)
@@ -83,14 +75,9 @@ unsigned WebGLUnsignedShortArray::byteLength() const {
 }
 
 PassRefPtr<WebGLArray> WebGLUnsignedShortArray::slice(unsigned offset, unsigned length) {
-    // Check to make sure the specified region is within the bounds of
-    // the WebGLArrayBuffer.
-    unsigned startByte = m_byteOffset + offset * sizeof(unsigned short);
-    unsigned limitByte = startByte + length * sizeof(unsigned short);
-    unsigned bufferLength = buffer()->byteLength();
-    if (startByte >= bufferLength || limitByte > bufferLength)
-        return 0;
-    return create(buffer(), startByte, length);
+    unsigned fullOffset = m_byteOffset + offset * sizeof(unsigned short);
+    clampOffsetAndNumElements<unsigned short>(buffer(), &fullOffset, &length);
+    return create(buffer(), fullOffset, length);
 }
 
 void WebGLUnsignedShortArray::set(WebGLUnsignedShortArray* array, unsigned offset, ExceptionCode& ec) {
index 3bad1b6..11a9594 100644 (file)
@@ -41,7 +41,7 @@ class WebGLUnsignedShortArray : public WebGLArray {
 
     static PassRefPtr<WebGLUnsignedShortArray> create(unsigned length);
     static PassRefPtr<WebGLUnsignedShortArray> create(unsigned short* array, unsigned length);
-    static PassRefPtr<WebGLUnsignedShortArray> create(PassRefPtr<WebGLArrayBuffer> buffer, int byteOffset, unsigned length);
+    static PassRefPtr<WebGLUnsignedShortArray> create(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset, unsigned length);
 
     unsigned short* data() { return static_cast<unsigned short*>(baseAddress()); }
 
@@ -87,7 +87,7 @@ class WebGLUnsignedShortArray : public WebGLArray {
     void set(WebGLUnsignedShortArray* array, unsigned offset, ExceptionCode& ec);
 
   private:
-    WebGLUnsignedShortArray(PassRefPtr<WebGLArrayBuffer> buffer,int byteOffset,unsigned length);
+    WebGLUnsignedShortArray(PassRefPtr<WebGLArrayBuffer> buffer, unsigned byteOffset,unsigned length);
     unsigned m_size;
 };