aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-08-10 15:41:59 +0200
committerLars Knoll <lars.knoll@qt.io>2018-08-23 08:13:00 +0000
commit271e0d56bce54c0a662fe0e948f28a1886b14a55 (patch)
tree2d6507de5f83d1c8952be3e660b311b1c45e5427 /src
parent8ee5dff21c3701a5a0dd1de9bed563da0aa12ef6 (diff)
Fix bugs in ArrayBuffer.prototype.slice
Change-Id: I6de8031a04c372a5309a878811da55b93b53da3d Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jsruntime/qv4arraybuffer.cpp13
-rw-r--r--src/qml/jsruntime/qv4object.cpp20
-rw-r--r--src/qml/jsruntime/qv4object_p.h2
-rw-r--r--src/qml/jsruntime/qv4regexpobject.cpp22
4 files changed, 31 insertions, 26 deletions
diff --git a/src/qml/jsruntime/qv4arraybuffer.cpp b/src/qml/jsruntime/qv4arraybuffer.cpp
index c52e9bf24e..dc8bce12a0 100644
--- a/src/qml/jsruntime/qv4arraybuffer.cpp
+++ b/src/qml/jsruntime/qv4arraybuffer.cpp
@@ -74,9 +74,9 @@ ReturnedValue ArrayBufferCtor::virtualCallAsConstructor(const FunctionObject *f,
}
-ReturnedValue ArrayBufferCtor::virtualCall(const FunctionObject *f, const Value *, const Value *argv, int argc)
+ReturnedValue ArrayBufferCtor::virtualCall(const FunctionObject *f, const Value *, const Value *, int)
{
- return virtualCallAsConstructor(f, argv, argc, f);
+ return f->engine()->throwTypeError();
}
ReturnedValue ArrayBufferCtor::method_isView(const FunctionObject *, const Value *, const Value *argv, int argc)
@@ -188,18 +188,21 @@ ReturnedValue ArrayBufferPrototype::method_slice(const FunctionObject *b, const
double final = (end < 0) ? qMax(a->d()->data->size + end, 0.) : qMin(end, (double)a->d()->data->size);
Scope scope(v4);
- ScopedFunctionObject constructor(scope, a->get(scope.engine->id_constructor()));
+ const FunctionObject *constructor = a->speciesConstructor(scope, scope.engine->arrayBufferCtor());
if (!constructor)
return v4->throwTypeError();
double newLen = qMax(final - first, 0.);
ScopedValue argument(scope, QV4::Encode(newLen));
QV4::Scoped<ArrayBuffer> newBuffer(scope, constructor->callAsConstructor(argument, 1));
- if (!newBuffer || newBuffer->d()->data->size < (int)newLen)
+ if (!newBuffer || newBuffer->d()->data->size < (int)newLen ||
+ newBuffer->isDetachedBuffer() || newBuffer->isSharedArrayBuffer() ||
+ newBuffer->sameValue(*a) ||
+ a->isDetachedBuffer())
return v4->throwTypeError();
memcpy(newBuffer->d()->data->data(), a->d()->data->data() + (uint)first, newLen);
- return Encode::undefined();
+ return newBuffer->asReturnedValue();
}
ReturnedValue ArrayBufferPrototype::method_toString(const FunctionObject *b, const Value *thisObject, const Value *, int)
diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp
index 6a6687661c..72f9f84bb2 100644
--- a/src/qml/jsruntime/qv4object.cpp
+++ b/src/qml/jsruntime/qv4object.cpp
@@ -960,6 +960,26 @@ bool Object::isArray() const
return false;
}
+const FunctionObject *Object::speciesConstructor(Scope &scope, const FunctionObject *defaultConstructor) const
+{
+ ScopedValue C(scope, get(scope.engine->id_constructor()));
+ if (C->isUndefined())
+ return defaultConstructor;
+ const Object *c = C->objectValue();
+ if (!c) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ ScopedValue S(scope, c->get(scope.engine->symbol_species()));
+ if (S->isNullOrUndefined())
+ return defaultConstructor;
+ if (!S->isFunctionObject()) {
+ scope.engine->throwTypeError();
+ return nullptr;
+ }
+ return static_cast<const FunctionObject *>(S.ptr);
+}
+
DEFINE_OBJECT_VTABLE(ArrayObject);
diff --git a/src/qml/jsruntime/qv4object_p.h b/src/qml/jsruntime/qv4object_p.h
index 431c378334..3dcee8addf 100644
--- a/src/qml/jsruntime/qv4object_p.h
+++ b/src/qml/jsruntime/qv4object_p.h
@@ -361,6 +361,8 @@ public:
bool isConcatSpreadable() const;
bool isArray() const;
+ const FunctionObject *speciesConstructor(Scope &scope, const FunctionObject *defaultConstructor) const;
+
protected:
static ReturnedValue virtualCallAsConstructor(const FunctionObject *f, const Value *argv, int argc, const Value *);
diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp
index dd33a9fc41..dd16110c28 100644
--- a/src/qml/jsruntime/qv4regexpobject.cpp
+++ b/src/qml/jsruntime/qv4regexpobject.cpp
@@ -765,26 +765,6 @@ ReturnedValue RegExpPrototype::method_get_source(const FunctionObject *f, const
return scope.engine->newString(re->toString())->asReturnedValue();
}
-static const FunctionObject *speciesConstructor(Scope &scope, const Object *o, const FunctionObject *defaultConstructor)
-{
- ScopedValue C(scope, o->get(scope.engine->id_constructor()));
- if (C->isUndefined())
- return defaultConstructor;
- const Object *c = C->objectValue();
- if (!c) {
- scope.engine->throwTypeError();
- return nullptr;
- }
- ScopedValue S(scope, c->get(scope.engine->symbol_species()));
- if (S->isNullOrUndefined())
- return defaultConstructor;
- if (!S->isFunctionObject()) {
- scope.engine->throwTypeError();
- return nullptr;
- }
- return static_cast<const FunctionObject *>(S.ptr);
-}
-
ReturnedValue RegExpPrototype::method_split(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc)
{
Scope scope(f);
@@ -805,7 +785,7 @@ ReturnedValue RegExpPrototype::method_split(const FunctionObject *f, const Value
flags = scope.engine->newString(flagsString + QLatin1Char('y'));
bool unicodeMatching = flagsString.contains(QLatin1Char('u'));
- const FunctionObject *C = speciesConstructor(scope, rx, scope.engine->regExpCtor());
+ const FunctionObject *C = rx->speciesConstructor(scope, scope.engine->regExpCtor());
if (!C)
return Encode::undefined();