diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jsruntime/qv4arraybuffer.cpp | 13 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 20 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 22 |
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(); |