From 7936ca39be951a96d9d737ea243ff4d8e79e8bf3 Mon Sep 17 00:00:00 2001 From: "dslomov@chromium.org" Date: Fri, 15 Nov 2013 16:37:15 +0000 Subject: [PATCH] Limit the size for typed arrays to MaxSmi. R=jkummerow@chromium.org LOG=Y BUG=319722 Review URL: https://codereview.chromium.org/73943004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17800 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/d8.cc | 3 ++ src/runtime.cc | 17 +++++++- src/runtime.h | 1 + src/typedarray.js | 3 ++ test/mjsunit/regress/regress-319722-ArrayBuffer.js | 47 ++++++++++++++++++++++ test/mjsunit/regress/regress-319722-TypedArrays.js | 45 +++++++++++++++++++++ 6 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 test/mjsunit/regress/regress-319722-ArrayBuffer.js create mode 100644 test/mjsunit/regress/regress-319722-TypedArrays.js diff --git a/src/d8.cc b/src/d8.cc index e855c85..d227ac3 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -1358,6 +1358,9 @@ bool Shell::SetOptions(int argc, char* argv[]) { if (strcmp(argv[i], "--stress-opt") == 0) { options.stress_opt = true; argv[i] = NULL; + } else if (strcmp(argv[i], "--nostress-opt") == 0) { + options.stress_opt = false; + argv[i] = NULL; } else if (strcmp(argv[i], "--stress-deopt") == 0) { options.stress_deopt = true; argv[i] = NULL; diff --git a/src/runtime.cc b/src/runtime.cc index 881020c..28506dd 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -917,6 +917,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) { ASSERT(byte_length % element_size == 0); size_t length = byte_length / element_size; + if (length > static_cast(Smi::kMaxValue)) { + return isolate->Throw(*isolate->factory()-> + NewRangeError("invalid_typed_array_length", + HandleVector(NULL, 0))); + } + Handle length_obj = isolate->factory()->NewNumberFromSize(length); holder->set_length(*length_obj); holder->set_weak_next(buffer->weak_first_view()); @@ -956,9 +962,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitializeFromArrayLike) { Handle buffer = isolate->factory()->NewJSArrayBuffer(); size_t length = NumberToSize(isolate, *length_obj); - if (length > (kMaxInt / element_size)) { + + if ((length > static_cast(Smi::kMaxValue)) || + (length > (kMaxInt / element_size))) { return isolate->Throw(*isolate->factory()-> - NewRangeError("invalid_array_buffer_length", + NewRangeError("invalid_typed_array_length", HandleVector(NULL, 0))); } size_t byte_length = length * element_size; @@ -14809,6 +14817,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalArrayConstructor) { } +RUNTIME_FUNCTION(MaybeObject*, Runtime_MaxSmi) { + return Smi::FromInt(Smi::kMaxValue); +} + + // ---------------------------------------------------------------------------- // Implementation of Runtime diff --git a/src/runtime.h b/src/runtime.h index 0ba07db..8b650e9 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -112,6 +112,7 @@ namespace internal { F(FlattenString, 1, 1) \ F(MigrateInstance, 1, 1) \ F(NotifyContextDisposed, 0, 1) \ + F(MaxSmi, 0, 1) \ \ /* Array join support */ \ F(PushIfAbsent, 2, 1) \ diff --git a/src/typedarray.js b/src/typedarray.js index 422dc4a..ca87f8b 100644 --- a/src/typedarray.js +++ b/src/typedarray.js @@ -87,6 +87,9 @@ macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE) function NAMEConstructByLength(obj, length) { var l = IS_UNDEFINED(length) ? 0 : ToPositiveInteger(length, "invalid_typed_array_length"); + if (l > %MaxSmi()) { + throw MakeRangeError("invalid_typed_array_length"); + } var byteLength = l * ELEMENT_SIZE; var buffer = new $ArrayBuffer(byteLength); %TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength); diff --git a/test/mjsunit/regress/regress-319722-ArrayBuffer.js b/test/mjsunit/regress/regress-319722-ArrayBuffer.js new file mode 100644 index 0000000..c8aed9e --- /dev/null +++ b/test/mjsunit/regress/regress-319722-ArrayBuffer.js @@ -0,0 +1,47 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --nostress-opt --allow-natives-syntax +var maxSize = %MaxSmi() + 1; +var ab = new ArrayBuffer(maxSize); + +function TestArray(constr) { + assertThrows(function() { + new constr(ab, 0, maxSize); + }, RangeError); +} + +TestArray(Uint8Array); +TestArray(Int8Array); +TestArray(Uint16Array); +TestArray(Int16Array); +TestArray(Uint32Array); +TestArray(Int32Array); +TestArray(Float32Array); +TestArray(Float64Array); +TestArray(Uint8ClampedArray); + diff --git a/test/mjsunit/regress/regress-319722-TypedArrays.js b/test/mjsunit/regress/regress-319722-TypedArrays.js new file mode 100644 index 0000000..0445e2d --- /dev/null +++ b/test/mjsunit/regress/regress-319722-TypedArrays.js @@ -0,0 +1,45 @@ + +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --nostress-opt --allow-natives-syntax +var maxSize = %MaxSmi() + 1; +function TestArray(constr) { + assertThrows(function() { + new constr(maxSize); + }, RangeError); +} + +TestArray(Uint8Array); +TestArray(Int8Array); +TestArray(Uint16Array); +TestArray(Int16Array); +TestArray(Uint32Array); +TestArray(Int32Array); +TestArray(Float32Array); +TestArray(Float64Array); +TestArray(Uint8ClampedArray); -- 2.7.4