aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp3
-rw-r--r--src/qml/jsruntime/qv4typedarray.cpp10
-rw-r--r--src/qml/jsruntime/qv4value_p.h14
-rw-r--r--tests/auto/qml/ecmascripttests/TestExpectations1
4 files changed, 24 insertions, 4 deletions
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index 59a2b9d913..95dd5444c3 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -94,7 +94,8 @@ ReturnedValue ArrayBufferCtor::method_isView(const FunctionObject *, const Value
void Heap::ArrayBuffer::init(size_t length)
{
Object::init();
- data = QTypedArrayData<char>::allocate(length + 1);
+ if (length < UINT_MAX)
+ data = QTypedArrayData<char>::allocate(length + 1);
if (!data) {
internalClass->engine->throwRangeError(QStringLiteral("ArrayBuffer: out of memory"));
return;
diff --git a/src/qml/jsruntime/qv4typedarray.cpp b/src/qml/jsruntime/qv4typedarray.cpp
index 81e4deb463..ea83f4940b 100644
--- a/src/qml/jsruntime/qv4typedarray.cpp
+++ b/src/qml/jsruntime/qv4typedarray.cpp
@@ -219,9 +219,12 @@ ReturnedValue TypedArrayCtor::callAsConstructor(const FunctionObject *f, const V
if (!argc || !argv[0].isObject()) {
// ECMA 6 22.2.1.1
- double l = argc ? argv[0].toNumber() : 0;
+ qint64 l = argc ? argv[0].toIndex() : 0;
if (scope.engine->hasException)
return Encode::undefined();
+ // ### lift UINT_MAX restriction
+ if (l < 0 || l > UINT_MAX)
+ return scope.engine->throwRangeError(QLatin1String("Index out of range."));
uint len = (uint)l;
if (l != len)
scope.engine->throwRangeError(QStringLiteral("Non integer length for typed array."));
@@ -315,7 +318,10 @@ ReturnedValue TypedArrayCtor::callAsConstructor(const FunctionObject *f, const V
return scope.engine->throwTypeError();
uint elementSize = operations[that->d()->type].bytesPerElement;
- Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(l * elementSize));
+ size_t bufferSize;
+ if (mul_overflow(size_t(l), size_t(elementSize), &bufferSize))
+ return scope.engine->throwRangeError(QLatin1String("new TypedArray: invalid length"));
+ Scoped<ArrayBuffer> newBuffer(scope, scope.engine->newArrayBuffer(bufferSize));
if (scope.engine->hasException)
return Encode::undefined();
diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h
index 97c6ea23ff..c3a927fa91 100644
--- a/src/qml/jsruntime/qv4value_p.h
+++ b/src/qml/jsruntime/qv4value_p.h
@@ -402,6 +402,7 @@ public:
inline int toInt32() const;
inline unsigned int toUInt32() const;
qint64 toLength() const;
+ inline qint64 toIndex() const;
bool toBoolean() const {
if (integerCompatible())
@@ -833,6 +834,19 @@ inline qint64 Value::toLength() const
return static_cast<qint64>(i);
}
+inline qint64 Value::toIndex() const
+{
+ qint64 idx;
+ if (Q_LIKELY(integerCompatible())) {
+ idx = int_32();
+ } else {
+ idx = static_cast<qint64>(Primitive::toInteger(isDouble() ? doubleValue() : toNumberImpl()));
+ }
+ if (idx > (static_cast<qint64>(1) << 53) - 1)
+ idx = -1;
+ return idx;
+}
+
inline double Value::toInteger() const
{
if (integerCompatible())
diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations
index 00b9b7f513..5d4afe5538 100644
--- a/tests/auto/qml/ecmascripttests/TestExpectations
+++ b/tests/auto/qml/ecmascripttests/TestExpectations
@@ -2819,7 +2819,6 @@ built-ins/TypedArrays/ctors/buffer-arg/use-custom-proto-if-object.js fails
built-ins/TypedArrays/ctors/buffer-arg/use-default-proto-if-custom-proto-is-not-object.js fails
built-ins/TypedArrays/ctors/length-arg/custom-proto-access-throws.js fails
built-ins/TypedArrays/ctors/length-arg/proto-from-ctor-realm.js fails
-built-ins/TypedArrays/ctors/length-arg/toindex-length.js fails
built-ins/TypedArrays/ctors/length-arg/undefined-newtarget-throws.js fails
built-ins/TypedArrays/ctors/length-arg/use-custom-proto-if-object.js fails
built-ins/TypedArrays/ctors/length-arg/use-default-proto-if-custom-proto-is-not-object.js fails