Fix bug in TypedArray.prototype.set and add tests
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jan 2016 19:16:30 +0000 (19:16 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Jan 2016 19:16:30 +0000 (19:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153309

Reviewed by Michael Saboff.

This patch fixes an issue with TypedArray.prototype.set where we would
assign a double to an unsigned without checking that the double was
in the range of the unsigned. Additionally, the patch also adds
tests for set for cases that were not covered before.

* runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
(JSC::genericTypedArrayViewProtoFuncSet):
* tests/stress/typedarray-set.js: Added.

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h
Source/JavaScriptCore/tests/stress/typedarray-set.js [new file with mode: 0644]

index 93e554c..90eddf9 100644 (file)
@@ -1,3 +1,19 @@
+2016-01-21  Keith Miller  <keith_miller@apple.com>
+
+        Fix bug in TypedArray.prototype.set and add tests
+        https://bugs.webkit.org/show_bug.cgi?id=153309
+
+        Reviewed by Michael Saboff.
+
+        This patch fixes an issue with TypedArray.prototype.set where we would
+        assign a double to an unsigned without checking that the double was
+        in the range of the unsigned. Additionally, the patch also adds
+        tests for set for cases that were not covered before.
+
+        * runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
+        (JSC::genericTypedArrayViewProtoFuncSet):
+        * tests/stress/typedarray-set.js: Added.
+
 2016-01-19  Ada Chan  <adachan@apple.com>
 
         Make it possible to enable VIDEO_PRESENTATION_MODE on other Cocoa platforms.
index 23bb536..36c0409 100644 (file)
@@ -75,7 +75,7 @@ EncodedJSValue JSC_HOST_CALL genericTypedArrayViewProtoFuncSet(ExecState* exec)
             return JSValue::encode(jsUndefined());
         if (offsetNumber < 0)
             return throwVMRangeError(exec, "Offset should not be negative");
-        offset = offsetNumber;
+        offset = static_cast<unsigned>(std::min(offsetNumber, static_cast<double>(std::numeric_limits<unsigned>::max())));
     } else
         offset = 0;
 
diff --git a/Source/JavaScriptCore/tests/stress/typedarray-set.js b/Source/JavaScriptCore/tests/stress/typedarray-set.js
new file mode 100644 (file)
index 0000000..fac5fc7
--- /dev/null
@@ -0,0 +1,27 @@
+load("./resources/typedarray-test-helper-functions.js");
+description("This test checks the behavior of the TypedArray.prototype.set function");
+
+shouldBe("Int32Array.prototype.set.length", "1");
+shouldBe("Int32Array.prototype.set.name", "'set'");
+
+shouldBeTrue("isSameFunctionForEachTypedArrayPrototype('set')");
+shouldBeTrue("testPrototypeReceivesArray('set', [undefined, this, { }, [ ], true, ''])");
+debug("");
+
+debug("1.0 Normal Calls");
+shouldBeTrue("testPrototypeFunction('set', '([2, 3, 4])', [1, 2, 3, 4, 5], undefined, [2, 3, 4, 4, 5])");
+debug("This next should pass because -.1 when converted to an integer is -0");
+shouldBeTrue("testPrototypeFunction('set', '([2, 3, 4], -.1)', [1, 2, 3, 4, 5], undefined, [2, 3, 4, 4, 5])");
+shouldBeTrue("testPrototypeFunction('set', '([2, 3, 4], 2)', [1, 2, 3, 4, 5], undefined, [1, 2, 2, 3, 4])");
+shouldBeTrue("testPrototypeFunction('set', '([], 5)', [1, 2, 3, 4, 5], undefined, [1, 2, 3, 4, 5])");
+shouldBeTrue("testPrototypeFunction('set', '([])', [1, 2, 3, 4, 5], undefined, [1, 2, 3, 4, 5])");
+debug("");
+
+debug("2.0 Bad Range Test");
+shouldThrow("testPrototypeFunction('set', '([], -1)', [1, 2, 3, 4, 5], false, false)", "'RangeError: Offset should not be negative'");
+shouldThrow("testPrototypeFunction('set', '([2, 3, 4], -1)', [1, 2, 3, 4, 5], false, false)", "'RangeError: Offset should not be negative'");
+shouldThrow("testPrototypeFunction('set', '([2, 3, 4], -1.23412)', [1, 2, 3, 4, 5], false, false)", "'RangeError: Offset should not be negative'");
+shouldThrow("testPrototypeFunction('set', '([2, 3, 4], 1000)', [1, 2, 3, 4, 5], false, false)", "'RangeError: Range consisting of offset and length are out of bounds'");
+shouldThrow("testPrototypeFunction('set', '([2, 3, 4], 1e42*1.2434325231)', [1, 2, 3, 4, 5], false, false)", "'RangeError: Range consisting of offset and length are out of bounds'");
+
+finishJSTest();