aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4dataview.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-08-10 18:01:54 +0200
committerLars Knoll <lars.knoll@qt.io>2018-08-23 08:13:11 +0000
commit653d5aa353f70e86d0b9a575435121c4a23184a4 (patch)
treedd9d550c6a860e30d6be8256341ba7222824b460 /src/qml/jsruntime/qv4dataview.cpp
parentb8009a27242920f40ce9361c0aec619cca864c64 (diff)
Fix DataView constructor to be spec compliant
Change-Id: I312f8e086b733e184b353d77452f5d4a1262469a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4dataview.cpp')
-rw-r--r--src/qml/jsruntime/qv4dataview.cpp62
1 files changed, 35 insertions, 27 deletions
diff --git a/src/qml/jsruntime/qv4dataview.cpp b/src/qml/jsruntime/qv4dataview.cpp
index 1a0503dded..3f0e2fd1a7 100644
--- a/src/qml/jsruntime/qv4dataview.cpp
+++ b/src/qml/jsruntime/qv4dataview.cpp
@@ -55,31 +55,56 @@ void Heap::DataViewCtor::init(QV4::ExecutionContext *scope)
Heap::FunctionObject::init(scope, QStringLiteral("DataView"));
}
-ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *)
+static uint toIndex(ExecutionEngine *e, const Value &v)
+{
+ if (v.isUndefined())
+ return 0;
+ double index = v.toInteger();
+ if (index < 0) {
+ e->throwRangeError(QStringLiteral("index out of range"));
+ return 0;
+ }
+ uint idx = static_cast<uint>(index);
+ if (idx != index) {
+ e->throwRangeError(QStringLiteral("index out of range"));
+ return 0;
+ }
+ return idx;
+}
+
+ReturnedValue DataViewCtor::virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *newTarget)
{
Scope scope(f->engine());
Scoped<ArrayBuffer> buffer(scope, argc ? argv[0] : Primitive::undefinedValue());
- if (!buffer || buffer->isDetachedBuffer())
+ if (!newTarget || !buffer)
+ return scope.engine->throwTypeError();
+
+ uint offset = ::toIndex(scope.engine, argc > 1 ? argv[1]: Primitive::undefinedValue());
+ if (scope.hasException())
+ return Encode::undefined();
+ if (buffer->isDetachedBuffer())
return scope.engine->throwTypeError();
- double bo = argc > 1 ? argv[1].toNumber() : 0;
- uint byteOffset = (uint)bo;
uint bufferLength = buffer->d()->data->size;
- double bl = argc < 3 || argv[2].isUndefined() ? (bufferLength - bo) : argv[2].toNumber();
- uint byteLength = (uint)bl;
- if (bo != byteOffset || bl != byteLength || byteOffset + byteLength > bufferLength)
+ if (offset > bufferLength)
+ return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
+
+ uint byteLength = (argc < 3 || argv[2].isUndefined()) ? (bufferLength - offset) : ::toIndex(scope.engine, argv[2]);
+ if (scope.hasException())
+ return Encode::undefined();
+ if (offset + byteLength > bufferLength)
return scope.engine->throwRangeError(QStringLiteral("DataView: constructor arguments out of range"));
Scoped<DataView> a(scope, scope.engine->memoryManager->allocate<DataView>());
a->d()->buffer.set(scope.engine, buffer->d());
a->d()->byteLength = byteLength;
- a->d()->byteOffset = byteOffset;
+ a->d()->byteOffset = offset;
return a.asReturnedValue();
}
-ReturnedValue DataViewCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc)
+ReturnedValue DataViewCtor::virtualCall(const FunctionObject *f, const Value *, const Value *, int)
{
- return virtualCallAsConstructor(f, argv, argc, f);
+ return f->engine()->throwTypeError();
}
void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
@@ -123,23 +148,6 @@ void DataViewPrototype::init(ExecutionEngine *engine, Object *ctor)
defineDefaultProperty(QStringLiteral("setUInt32"), method_set<unsigned int>, 1);
}
-static uint toIndex(ExecutionEngine *e, const Value &v)
-{
- if (v.isUndefined())
- return 0;
- double index = v.toInteger();
- if (index < 0) {
- e->throwRangeError(QStringLiteral("index out of range"));
- return 0;
- }
- uint idx = static_cast<uint>(index);
- if (idx != index) {
- e->throwRangeError(QStringLiteral("index out of range"));
- return 0;
- }
- return idx;
-}
-
ReturnedValue DataViewPrototype::method_get_buffer(const FunctionObject *b, const Value *thisObject, const Value *, int)
{
const DataView *v = thisObject->as<DataView>();