diff options
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject.cpp | 6 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4argumentsobject_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 32 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4value_p.h | 13 | ||||
-rw-r--r-- | tests/auto/qml/ecmascripttests/TestExpectations | 45 |
7 files changed, 47 insertions, 69 deletions
diff --git a/src/qml/jsruntime/qv4argumentsobject.cpp b/src/qml/jsruntime/qv4argumentsobject.cpp index de00ac8984..d3ca573a2e 100644 --- a/src/qml/jsruntime/qv4argumentsobject.cpp +++ b/src/qml/jsruntime/qv4argumentsobject.cpp @@ -242,10 +242,8 @@ ReturnedValue ArgumentsSetterFunction::call(const FunctionObject *setter, const return Encode::undefined(); } -uint ArgumentsObject::getLength(const Managed *m) +qint64 ArgumentsObject::getLength(const Managed *m) { const ArgumentsObject *a = static_cast<const ArgumentsObject *>(m); - if (a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->isInteger()) - return a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->integerValue(); - return Primitive::toUInt32(a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->doubleValue()); + return a->propertyData(Heap::ArgumentsObject::LengthPropertyIndex)->toLength(); } diff --git a/src/qml/jsruntime/qv4argumentsobject_p.h b/src/qml/jsruntime/qv4argumentsobject_p.h index 9264f938e2..01e2c10090 100644 --- a/src/qml/jsruntime/qv4argumentsobject_p.h +++ b/src/qml/jsruntime/qv4argumentsobject_p.h @@ -149,7 +149,7 @@ struct ArgumentsObject: Object { static bool putIndexed(Managed *m, uint index, const Value &value); static bool deleteIndexedProperty(Managed *m, uint index); static PropertyAttributes queryIndexed(const Managed *m, uint index); - static uint getLength(const Managed *m); + static qint64 getLength(const Managed *m); void fullyCreate(); diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index bd019d3bcb..37c386d781 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -548,19 +548,31 @@ ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value if (!instance) RETURN_UNDEFINED(); - uint len = instance->getLength(); - - ScopedArrayObject newArray(scope, scope.engine->newArrayObject()); + qint64 len = instance->getLength(); double rs = (argc ? argv[0] : Primitive::undefinedValue()).toInteger(); - uint start; + qint64 start; if (rs < 0) - start = (uint) qMax(0., len + rs); + start = static_cast<qint64>(qMax(0., len + rs)); else - start = (uint) qMin(rs, (double)len); + start = static_cast<qint64>(qMin(rs, static_cast<double>(len))); + + qint64 deleteCount = 0; + qint64 itemCount = 0; + if (argc == 1) { + deleteCount = len - start; + } else if (argc > 1){ + itemCount = argc - 2; + double dc = argv[1].toInteger(); + deleteCount = static_cast<qint64>(qMin(qMax(dc, 0.), double(len - start))); + } - uint deleteCount = (uint)qMin(qMax((argc > 1 ? argv[1] : Primitive::undefinedValue()).toInteger(), 0.), (double)(len - start)); + if (len + itemCount - deleteCount > /*(static_cast<qint64>(1) << 53) - 1*/ UINT_MAX - 1) + return scope.engine->throwTypeError(); + if (deleteCount > /*(static_cast<qint64>(1) << 53) - 1*/ UINT_MAX - 1) + return scope.engine->throwRangeError(QString::fromLatin1("Array length out of range.")); + ScopedArrayObject newArray(scope, scope.engine->newArrayObject()); newArray->arrayReserve(deleteCount); ScopedValue v(scope); for (uint i = 0; i < deleteCount; ++i) { @@ -572,7 +584,6 @@ ReturnedValue ArrayPrototype::method_splice(const FunctionObject *b, const Value } newArray->setArrayLengthUnchecked(deleteCount); - uint itemCount = argc < 2 ? 0 : argc - 2; if (itemCount < deleteCount) { for (uint k = start; k < len - deleteCount; ++k) { @@ -873,12 +884,15 @@ ReturnedValue ArrayPrototype::method_map(const FunctionObject *b, const Value *t if (!instance) RETURN_UNDEFINED(); - uint len = instance->getLength(); + qint64 len = instance->getLength(); if (!argc || !argv->isFunctionObject()) THROW_TYPE_ERROR(); const FunctionObject *callback = static_cast<const FunctionObject *>(argv); + if (len > UINT_MAX - 1) + return scope.engine->throwRangeError(QString::fromLatin1("Array length out of range.")); + ScopedArrayObject a(scope, scope.engine->newArrayObject()); a->arrayReserve(len); a->setArrayLengthUnchecked(len); diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index 170ad9f556..d7cad2231e 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -1034,11 +1034,11 @@ void Object::copyArrayData(Object *other) setArrayLengthUnchecked(other->getLength()); } -uint Object::getLength(const Managed *m) +qint64 Object::getLength(const Managed *m) { Scope scope(static_cast<const Object *>(m)->engine()); ScopedValue v(scope, static_cast<Object *>(const_cast<Managed *>(m))->get(scope.engine->id_length())); - return v->toUInt32(); + return v->toLength(); } // 'var' is 'V' in 15.3.5.3. @@ -1136,12 +1136,10 @@ void Heap::ArrayObject::init(const QStringList &list) a->setArrayLengthUnchecked(len); } -uint ArrayObject::getLength(const Managed *m) +qint64 ArrayObject::getLength(const Managed *m) { const ArrayObject *a = static_cast<const ArrayObject *>(m); - if (a->propertyData(Heap::ArrayObject::LengthPropertyIndex)->isInteger()) - return a->propertyData(Heap::ArrayObject::LengthPropertyIndex)->integerValue(); - return Primitive::toUInt32(a->propertyData(Heap::ArrayObject::LengthPropertyIndex)->doubleValue()); + return a->propertyData(Heap::ArrayObject::LengthPropertyIndex)->toLength(); } QStringList ArrayObject::toQStringList() const diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h index 79ffef47ba..7b1046d6ee 100644 --- a/src/qml/jsruntime/qv4object_p.h +++ b/src/qml/jsruntime/qv4object_p.h @@ -174,7 +174,7 @@ struct ObjectVTable PropertyAttributes (*queryIndexed)(const Managed *, uint index); bool (*deleteProperty)(Managed *m, String *name); bool (*deleteIndexedProperty)(Managed *m, uint index); - uint (*getLength)(const Managed *m); + qint64 (*getLength)(const Managed *m); void (*advanceIterator)(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); ReturnedValue (*instanceOf)(const Object *typeObject, const Value &var); }; @@ -406,7 +406,7 @@ public: { return vtable()->deleteIndexedProperty(this, index); } void advanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes) { vtable()->advanceIterator(this, it, name, index, p, attributes); } - uint getLength() const { return vtable()->getLength(this); } + quint64 getLength() const { return vtable()->getLength(this); } ReturnedValue instanceOf(const Value &var) const { return vtable()->instanceOf(this, var); } @@ -422,7 +422,7 @@ protected: static bool deleteProperty(Managed *m, String *name); static bool deleteIndexedProperty(Managed *m, uint index); static void advanceIterator(Managed *m, ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attributes); - static uint getLength(const Managed *m); + static qint64 getLength(const Managed *m); static ReturnedValue instanceOf(const Object *typeObject, const Value &var); private: @@ -504,7 +504,7 @@ struct ArrayObject: Object { void init(ExecutionEngine *engine); using Object::getLength; - static uint getLength(const Managed *m); + static qint64 getLength(const Managed *m); QStringList toQStringList() const; }; diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 42c0370138..03c9eda0f2 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -389,6 +389,7 @@ public: int toUInt16() const; inline int toInt32() const; inline unsigned int toUInt32() const; + qint64 toLength() const; bool toBoolean() const { if (integerCompatible()) @@ -789,6 +790,18 @@ inline unsigned int Value::toUInt32() const return static_cast<unsigned int>(toInt32()); } +inline qint64 Value::toLength() const +{ + if (Q_LIKELY(integerCompatible())) + return int_32(); + double i = Primitive::toInteger(isDouble() ? doubleValue() : toNumberImpl()); + if (i <= 0) + return 0; + if (i > (static_cast<qint64>(1) << 53) - 1) + return (static_cast<qint64>(1) << 53) - 1; + return static_cast<qint64>(i); +} + inline double Value::toInteger() const { if (integerCompatible()) diff --git a/tests/auto/qml/ecmascripttests/TestExpectations b/tests/auto/qml/ecmascripttests/TestExpectations index e025646443..55007189b8 100644 --- a/tests/auto/qml/ecmascripttests/TestExpectations +++ b/tests/auto/qml/ecmascripttests/TestExpectations @@ -211,12 +211,7 @@ built-ins/Array/prototype/entries/name built-ins/Array/prototype/entries/prop-desc built-ins/Array/prototype/entries/returns-iterator built-ins/Array/prototype/entries/returns-iterator-from-object -built-ins/Array/prototype/every/15.4.4.16-3-12 -built-ins/Array/prototype/every/15.4.4.16-3-14 -built-ins/Array/prototype/every/15.4.4.16-3-25 built-ins/Array/prototype/every/15.4.4.16-3-29 -built-ins/Array/prototype/every/15.4.4.16-3-7 -built-ins/Array/prototype/every/15.4.4.16-3-8 built-ins/Array/prototype/fill/coerced-indexes built-ins/Array/prototype/fill/fill-values built-ins/Array/prototype/fill/fill-values-custom-start-and-end @@ -233,9 +228,6 @@ built-ins/Array/prototype/fill/return-abrupt-from-start-as-symbol built-ins/Array/prototype/fill/return-abrupt-from-this-length built-ins/Array/prototype/fill/return-abrupt-from-this-length-as-symbol built-ins/Array/prototype/fill/return-this -built-ins/Array/prototype/filter/15.4.4.20-3-12 -built-ins/Array/prototype/filter/15.4.4.20-3-25 -built-ins/Array/prototype/filter/15.4.4.20-3-7 built-ins/Array/prototype/filter/create-ctor-non-object built-ins/Array/prototype/filter/create-proto-from-ctor-realm-array built-ins/Array/prototype/filter/create-proto-from-ctor-realm-non-array @@ -251,9 +243,6 @@ built-ins/Array/prototype/findIndex/return-abrupt-from-this-length-as-symbol built-ins/Array/prototype/findIndex/return-index-predicate-result-is-true built-ins/Array/prototype/find/return-abrupt-from-this-length-as-symbol built-ins/Array/prototype/find/return-found-value-predicate-result-is-true -built-ins/Array/prototype/forEach/15.4.4.18-3-12 -built-ins/Array/prototype/forEach/15.4.4.18-3-25 -built-ins/Array/prototype/forEach/15.4.4.18-3-7 built-ins/Array/prototype/includes/fromIndex-equal-or-greater-length-returns-false built-ins/Array/prototype/includes/fromIndex-infinity built-ins/Array/prototype/includes/fromIndex-minus-zero @@ -278,13 +267,8 @@ built-ins/Array/prototype/includes/tointeger-fromindex built-ins/Array/prototype/includes/tolength-length built-ins/Array/prototype/includes/using-fromindex built-ins/Array/prototype/includes/values-are-not-cached -built-ins/Array/prototype/indexOf/15.4.4.14-3-12 -built-ins/Array/prototype/indexOf/15.4.4.14-3-14 -built-ins/Array/prototype/indexOf/15.4.4.14-3-25 built-ins/Array/prototype/indexOf/15.4.4.14-3-28 built-ins/Array/prototype/indexOf/15.4.4.14-3-29 -built-ins/Array/prototype/indexOf/15.4.4.14-3-7 -built-ins/Array/prototype/indexOf/15.4.4.14-3-8 built-ins/Array/prototype/join/S15.4.4.5_A4_T3 built-ins/Array/prototype/keys/iteration built-ins/Array/prototype/keys/iteration-mutable @@ -293,19 +277,8 @@ built-ins/Array/prototype/keys/name built-ins/Array/prototype/keys/prop-desc built-ins/Array/prototype/keys/returns-iterator built-ins/Array/prototype/keys/returns-iterator-from-object -built-ins/Array/prototype/lastIndexOf/15.4.4.15-3-12 -built-ins/Array/prototype/lastIndexOf/15.4.4.15-3-25 built-ins/Array/prototype/lastIndexOf/15.4.4.15-3-28 -built-ins/Array/prototype/lastIndexOf/15.4.4.15-3-7 -built-ins/Array/prototype/map/15.4.4.19-3-12 -built-ins/Array/prototype/map/15.4.4.19-3-14 -built-ins/Array/prototype/map/15.4.4.19-3-25 -built-ins/Array/prototype/map/15.4.4.19-3-28 -built-ins/Array/prototype/map/15.4.4.19-3-29 -built-ins/Array/prototype/map/15.4.4.19-3-7 -built-ins/Array/prototype/map/15.4.4.19-3-8 built-ins/Array/prototype/map/create-ctor-non-object -built-ins/Array/prototype/map/create-non-array-invalid-len built-ins/Array/prototype/map/create-proto-from-ctor-realm-array built-ins/Array/prototype/map/create-proto-from-ctor-realm-non-array built-ins/Array/prototype/map/create-proxy @@ -329,16 +302,8 @@ built-ins/Array/prototype/push/S15.4.4.7_A2_T2 built-ins/Array/prototype/push/S15.4.4.7_A4_T1 built-ins/Array/prototype/push/S15.4.4.7_A4_T3 built-ins/Array/prototype/push/throws-if-integer-limit-exceeded -built-ins/Array/prototype/reduce/15.4.4.21-3-12 -built-ins/Array/prototype/reduce/15.4.4.21-3-25 -built-ins/Array/prototype/reduce/15.4.4.21-3-7 -built-ins/Array/prototype/reduceRight/15.4.4.22-3-12 -built-ins/Array/prototype/reduceRight/15.4.4.22-3-25 -built-ins/Array/prototype/reduceRight/15.4.4.22-3-7 built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-object built-ins/Array/prototype/reverse/length-exceeding-integer-limit-with-proxy -built-ins/Array/prototype/reverse/S15.4.4.8_A3_T3 -built-ins/Array/prototype/shift/S15.4.4.9_A3_T3 built-ins/Array/prototype/slice/create-ctor-non-object built-ins/Array/prototype/slice/create-non-array-invalid-len built-ins/Array/prototype/slice/create-proto-from-ctor-realm-array @@ -358,19 +323,11 @@ built-ins/Array/prototype/slice/length-exceeding-integer-limit-proxied-array built-ins/Array/prototype/slice/S15.4.4.10_A3_T1 built-ins/Array/prototype/slice/S15.4.4.10_A3_T2 built-ins/Array/prototype/slice/S15.4.4.10_A3_T3 -built-ins/Array/prototype/some/15.4.4.17-3-12 -built-ins/Array/prototype/some/15.4.4.17-3-14 -built-ins/Array/prototype/some/15.4.4.17-3-25 built-ins/Array/prototype/some/15.4.4.17-3-28 built-ins/Array/prototype/some/15.4.4.17-3-29 -built-ins/Array/prototype/some/15.4.4.17-3-7 -built-ins/Array/prototype/some/15.4.4.17-3-8 built-ins/Array/prototype/sort/comparefn-nonfunction-call-throws -built-ins/Array/prototype/sort/S15.4.4.11_A4_T3 -built-ins/Array/prototype/splice/called_with_one_argument built-ins/Array/prototype/splice/clamps-length-to-integer-limit built-ins/Array/prototype/splice/create-ctor-non-object -built-ins/Array/prototype/splice/create-non-array-invalid-len built-ins/Array/prototype/splice/create-proto-from-ctor-realm-array built-ins/Array/prototype/splice/create-proto-from-ctor-realm-non-array built-ins/Array/prototype/splice/create-proxy @@ -389,7 +346,6 @@ built-ins/Array/prototype/splice/length-exceeding-integer-limit-shrink-array built-ins/Array/prototype/splice/length-near-integer-limit-grow-array built-ins/Array/prototype/splice/S15.4.4.12_A3_T1 built-ins/Array/prototype/splice/S15.4.4.12_A3_T3 -built-ins/Array/prototype/splice/throws-if-integer-limit-exceeded built-ins/Array/prototype/Symbol.iterator built-ins/Array/prototype/Symbol.unscopables/prop-desc built-ins/Array/prototype/Symbol.unscopables/value @@ -399,7 +355,6 @@ built-ins/Array/prototype/toLocaleString/S15.4.4.3_A1_T1 built-ins/Array/prototype/toLocaleString/S15.4.4.3_A3_T1 built-ins/Array/prototype/unshift/clamps-to-integer-limit built-ins/Array/prototype/unshift/length-near-integer-limit -built-ins/Array/prototype/unshift/S15.4.4.13_A3_T2 built-ins/Array/prototype/unshift/throws-if-integer-limit-exceeded built-ins/Array/prototype/values/iteration built-ins/Array/prototype/values/iteration-mutable |