Fix data view accessors to throw execptions on offsets bigger than size_t.
authordslomov@chromium.org <dslomov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 18 Nov 2013 15:16:22 +0000 (15:16 +0000)
committerdslomov@chromium.org <dslomov@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 18 Nov 2013 15:16:22 +0000 (15:16 +0000)
R=jkummerow@chromium.org
BUG=v8:3013
LOG=Y

Review URL: https://codereview.chromium.org/74583003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17840 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/runtime.cc
src/v8conversions.h
test/mjsunit/harmony/dataview-accessors.js

index 28506dd..449d8a3 100644 (file)
@@ -1212,7 +1212,10 @@ inline static bool DataViewGetValue(
     Handle<Object> byte_offset_obj,
     bool is_little_endian,
     T* result) {
-  size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
 
   size_t data_view_byte_offset =
@@ -1253,7 +1256,10 @@ static bool DataViewSetValue(
     Handle<Object> byte_offset_obj,
     bool is_little_endian,
     T data) {
-  size_t byte_offset = NumberToSize(isolate, *byte_offset_obj);
+  size_t byte_offset = 0;
+  if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) {
+    return false;
+  }
   Handle<JSArrayBuffer> buffer(JSArrayBuffer::cast(data_view->buffer()));
 
   size_t data_view_byte_offset =
index d3da9f8..b449c88 100644 (file)
@@ -55,26 +55,41 @@ double StringToDouble(UnicodeCache* unicode_cache,
 // Converts a string into an integer.
 double StringToInt(UnicodeCache* unicode_cache, String* str, int radix);
 
-// Converts a number into size_t.
-inline size_t NumberToSize(Isolate* isolate,
-                           Object* number) {
+inline bool TryNumberToSize(Isolate* isolate,
+                            Object* number, size_t* result) {
   SealHandleScope shs(isolate);
   if (number->IsSmi()) {
     int value = Smi::cast(number)->value();
-    CHECK_GE(value, 0);
     ASSERT(
-      static_cast<unsigned>(Smi::kMaxValue)
-        <= std::numeric_limits<size_t>::max());
-    return static_cast<size_t>(value);
+        static_cast<unsigned>(Smi::kMaxValue)
+          <= std::numeric_limits<size_t>::max());
+    if (value >= 0) {
+      *result = static_cast<size_t>(value);
+      return true;
+    }
+    return false;
   } else {
     ASSERT(number->IsHeapNumber());
     double value = HeapNumber::cast(number)->value();
-    CHECK(value >= 0 &&
-          value <= std::numeric_limits<size_t>::max());
-    return static_cast<size_t>(value);
+    if (value >= 0 &&
+        value <= std::numeric_limits<size_t>::max()) {
+      *result = static_cast<size_t>(value);
+      return true;
+    } else {
+      return false;
+    }
   }
 }
 
+// Converts a number into size_t.
+inline size_t NumberToSize(Isolate* isolate,
+                           Object* number) {
+  size_t result;
+  bool is_valid = TryNumberToSize(isolate, number, &result);
+  CHECK(is_valid);
+  return result;
+}
+
 } }  // namespace v8::internal
 
 #endif  // V8_V8CONVERSIONS_H_
index 7b03da7..c54f8cc 100644 (file)
@@ -114,11 +114,13 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Int8", undefined, 0);
   test(isTestingGet, "Int8", 8, -128);
   test(isTestingGet, "Int8", 15, -1);
+  test(isTestingGet, "Int8", 1e12, undefined);
 
   test(isTestingGet, "Uint8", 0, 0);
   test(isTestingGet, "Uint8", undefined, 0);
   test(isTestingGet, "Uint8", 8, 128);
   test(isTestingGet, "Uint8", 15, 255);
+  test(isTestingGet, "Uint8", 1e12, undefined);
 
   // Little endian.
   test(isTestingGet, "Int16", 0, 256, true);
@@ -126,6 +128,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Int16", 5, 26213, true);
   test(isTestingGet, "Int16", 9, -32127, true);
   test(isTestingGet, "Int16", 14, -2, true);
+  test(isTestingGet, "Int16", 1e12, undefined, true);
 
   // Big endian.
   test(isTestingGet, "Int16", 0, 1);
@@ -133,6 +136,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Int16", 5, 25958);
   test(isTestingGet, "Int16", 9, -32382);
   test(isTestingGet, "Int16", 14, -257);
+  test(isTestingGet, "Int16", 1e12, undefined);
 
   // Little endian.
   test(isTestingGet, "Uint16", 0, 256, true);
@@ -140,6 +144,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Uint16", 5, 26213, true);
   test(isTestingGet, "Uint16", 9, 33409, true);
   test(isTestingGet, "Uint16", 14, 65534, true);
+  test(isTestingGet, "Uint16", 1e12, undefined, true);
 
   // Big endian.
   test(isTestingGet, "Uint16", 0, 1);
@@ -147,6 +152,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Uint16", 5, 25958);
   test(isTestingGet, "Uint16", 9, 33154);
   test(isTestingGet, "Uint16", 14, 65279);
+  test(isTestingGet, "Uint16", 1e12, undefined);
 
   // Little endian.
   test(isTestingGet, "Int32", 0, 50462976, true);
@@ -155,6 +161,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Int32", 6, -2122291354, true);
   test(isTestingGet, "Int32", 9, -58490239, true);
   test(isTestingGet, "Int32", 12,-66052, true);
+  test(isTestingGet, "Int32", 1e12, undefined, true);
 
   // Big endian.
   test(isTestingGet, "Int32", 0, 66051);
@@ -163,6 +170,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Int32", 6, 1718059137);
   test(isTestingGet, "Int32", 9, -2122152964);
   test(isTestingGet, "Int32", 12, -50462977);
+  test(isTestingGet, "Int32", 1e12, undefined);
 
   // Little endian.
   test(isTestingGet, "Uint32", 0, 50462976, true);
@@ -171,6 +179,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Uint32", 6, 2172675942, true);
   test(isTestingGet, "Uint32", 9, 4236477057, true);
   test(isTestingGet, "Uint32", 12,4294901244, true);
+  test(isTestingGet, "Uint32", 1e12, undefined, true);
 
   // Big endian.
   test(isTestingGet, "Uint32", 0, 66051);
@@ -179,6 +188,7 @@ function runIntegerTestCases(isTestingGet, array, start, length) {
   test(isTestingGet, "Uint32", 6, 1718059137);
   test(isTestingGet, "Uint32", 9, 2172814332);
   test(isTestingGet, "Uint32", 12, 4244504319);
+  test(isTestingGet, "Uint32", 1e12, undefined);
 }
 
 function testFloat(isTestingGet, func, array, start, expected) {
@@ -192,6 +202,7 @@ function testFloat(isTestingGet, func, array, start, expected) {
   test(isTestingGet, func, 7, expected, true);
   createDataView(array, 10, true, start);
   test(isTestingGet, func, 10, expected, true);
+  test(isTestingGet, func, 1e12, undefined, true);
 
   // Big endian.
   createDataView(array, 0, false);
@@ -203,6 +214,7 @@ function testFloat(isTestingGet, func, array, start, expected) {
   test(isTestingGet, func, 7, expected, false);
   createDataView(array, 10, false);
   test(isTestingGet, func, 10, expected, false);
+  test(isTestingGet, func, 1e12, undefined, false);
 }
 
 function runFloatTestCases(isTestingGet, start) {