diff options
author | Lars Knoll <[email protected]> | 2013-10-22 13:26:08 +0200 |
---|---|---|
committer | The Qt Project <[email protected]> | 2013-10-29 10:39:01 +0100 |
commit | ffcdbfa03f8bb36b521f8c1a703ee24085fe25bd (patch) | |
tree | ddee0370444a4f71cabb7847e7f1eb758622bd9f | |
parent | af22149dd8daf593182fec978f15dc1667c9cf8d (diff) |
Protect write accesses to objects
Don't write to objects if we have a pending exception to
avoid any side effects.
Change-Id: I9f93a9195a652dbae7033cc6ebb355d5d86e9b5e
Reviewed-by: Simon Hausmann <[email protected]>
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 54 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 8 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 24 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4globalobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4jsonobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4numberobject.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4object.cpp | 23 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4objectproto.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4sequenceobject.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4string.cpp | 5 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlcontextwrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper.cpp | 3 | ||||
-rw-r--r-- | src/quick/items/context2d/qquickcontext2d.cpp | 3 |
18 files changed, 132 insertions, 23 deletions
diff --git a/src/qml/jsruntime/qv4arrayobject.cpp b/src/qml/jsruntime/qv4arrayobject.cpp index b1308e12fb..22ad10560e 100644 --- a/src/qml/jsruntime/qv4arrayobject.cpp +++ b/src/qml/jsruntime/qv4arrayobject.cpp @@ -213,6 +213,8 @@ ReturnedValue ArrayPrototype::method_join(SimpleCallContext *ctx) R += r4; e = a->getIndexed(i); + if (scope.hasException()) + return Encode::undefined(); if (!e->isNullOrUndefined()) R += e->toString(ctx)->toQString(); } @@ -231,6 +233,8 @@ ReturnedValue ArrayPrototype::method_join(SimpleCallContext *ctx) name = Primitive::fromDouble(k).toString(ctx); r12 = self->get(name); + if (scope.hasException()) + return Encode::undefined(); if (!r12->isNullOrUndefined()) R += r12->toString(ctx)->toQString(); @@ -255,8 +259,12 @@ ReturnedValue ArrayPrototype::method_pop(SimpleCallContext *ctx) } ScopedValue result(scope, instance->getIndexed(len - 1)); + if (scope.hasException()) + return Encode::undefined(); instance->deleteIndexedProperty(len - 1); + if (scope.hasException()) + return Encode::undefined(); if (instance->isArrayObject()) instance->setArrayLengthUnchecked(len - 1); else @@ -334,10 +342,14 @@ ReturnedValue ArrayPrototype::method_reverse(SimpleCallContext *ctx) bool loExists, hiExists; lval = instance->getIndexed(lo, &loExists); hval = instance->getIndexed(hi, &hiExists); + if (scope.hasException()) + return Encode::undefined(); if (hiExists) instance->putIndexed(lo, hval); else instance->deleteIndexedProperty(lo); + if (scope.hasException()) + return Encode::undefined(); if (loExists) instance->putIndexed(hi, lval); else @@ -387,12 +399,16 @@ ReturnedValue ArrayPrototype::method_shift(SimpleCallContext *ctx) for (uint k = 1; k < len; ++k) { bool exists; v = instance->getIndexed(k, &exists); + if (scope.hasException()) + return Encode::undefined(); if (exists) instance->putIndexed(k - 1, v); else instance->deleteIndexedProperty(k - 1); } instance->deleteIndexedProperty(len - 1); + if (scope.hasException()) + return Encode::undefined(); } if (instance->isArrayObject()) @@ -435,9 +451,10 @@ ReturnedValue ArrayPrototype::method_slice(SimpleCallContext *ctx) for (uint i = start; i < end; ++i) { bool exists; v = o->getIndexed(i, &exists); - if (exists) { + if (scope.hasException()) + return Encode::undefined(); + if (exists) result->arraySet(n, v); - } ++n; } return result.asReturnedValue(); @@ -479,6 +496,8 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx) newArray->arrayReserve(deleteCount); for (uint i = 0; i < deleteCount; ++i) { newArray->arrayData[i].value = instance->getIndexed(start + i); + if (scope.hasException()) + return Encode::undefined(); newArray->arrayDataLen = i + 1; } newArray->setArrayLengthUnchecked(deleteCount); @@ -490,28 +509,42 @@ ReturnedValue ArrayPrototype::method_splice(SimpleCallContext *ctx) for (uint k = start; k < len - deleteCount; ++k) { bool exists; v = instance->getIndexed(k + deleteCount, &exists); + if (scope.hasException()) + return Encode::undefined(); if (exists) instance->putIndexed(k + itemCount, v); else instance->deleteIndexedProperty(k + itemCount); + if (scope.hasException()) + return Encode::undefined(); } - for (uint k = len; k > len - deleteCount + itemCount; --k) + for (uint k = len; k > len - deleteCount + itemCount; --k) { instance->deleteIndexedProperty(k - 1); + if (scope.hasException()) + return Encode::undefined(); + } } else if (itemCount > deleteCount) { uint k = len - deleteCount; while (k > start) { bool exists; v = instance->getIndexed(k + deleteCount - 1, &exists); + if (scope.hasException()) + return Encode::undefined(); if (exists) instance->putIndexed(k + itemCount - 1, v); else instance->deleteIndexedProperty(k + itemCount - 1); + if (scope.hasException()) + return Encode::undefined(); --k; } } - for (uint i = 0; i < itemCount; ++i) + for (uint i = 0; i < itemCount; ++i) { instance->putIndexed(start + i, ctx->callData->args[i + 2]); + if (scope.hasException()) + return Encode::undefined(); + } ctx->strictMode = true; instance->put(ctx->engine->id_length, ScopedValue(scope, Primitive::fromDouble(len - deleteCount + itemCount))); @@ -582,16 +615,13 @@ ReturnedValue ArrayPrototype::method_indexOf(SimpleCallContext *ctx) if (!len) return Encode(-1); - ScopedValue searchValue(scope); + ScopedValue searchValue(scope, ctx->callData->argument(0)); uint fromIndex = 0; - if (ctx->callData->argc >= 1) - searchValue = ctx->callData->args[0]; - else - searchValue = Primitive::undefinedValue(); - if (ctx->callData->argc >= 2) { double f = ctx->callData->args[1].toInteger(); + if (scope.hasException()) + return Encode::undefined(); if (f >= len) return Encode(-1); if (f < 0) @@ -634,6 +664,8 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx) if (ctx->callData->argc >= 2) { double f = ctx->callData->args[1].toInteger(); + if (scope.hasException()) + return Encode::undefined(); if (f > 0) f = qMin(f, (double)(len - 1)); else if (f < 0) { @@ -649,6 +681,8 @@ ReturnedValue ArrayPrototype::method_lastIndexOf(SimpleCallContext *ctx) --k; bool exists; v = instance->getIndexed(k, &exists); + if (scope.hasException()) + return Encode::undefined(); if (exists && __qmljs_strict_equal(v, searchValue)) return Encode(k); } diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index cf39d7df4f..bb11011669 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -808,7 +808,13 @@ QmlExtensions *ExecutionEngine::qmlExtensions() ReturnedValue ExecutionEngine::throwException(const ValueRef value) { -// Q_ASSERT(!hasException); + // we can get in here with an exception already set, as the runtime + // doesn't check after every operation that can throw. + // in this case preserve the first exception to give correct error + // information + if (hasException) + return Encode::undefined(); + hasException = true; exceptionValue = value; QV4::Scope scope(this); diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index b2ef86525f..7c61a34190 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -250,6 +250,8 @@ ReturnedValue FunctionCtor::construct(Managed *that, CallData *callData) } body = callData->args[callData->argc - 1].toString(ctx)->toQString(); } + if (ctx->engine->hasException) + return Encode::undefined(); QString function = QLatin1String("function(") + arguments + QLatin1String("){") + body + QLatin1String("}"); @@ -431,6 +433,9 @@ ReturnedValue ScriptFunction::construct(Managed *that, CallData *callData) { ExecutionEngine *v4 = that->engine(); Scope scope(v4); + if (scope.hasException()) + return Encode::undefined(); + Scoped<ScriptFunction> f(scope, static_cast<ScriptFunction *>(that)); InternalClass *ic = v4->objectClass; @@ -456,6 +461,9 @@ ReturnedValue ScriptFunction::call(Managed *that, CallData *callData) void *stackSpace; ExecutionContext *context = f->engine()->current; Scope scope(context); + if (scope.hasException()) + return Encode::undefined(); + CallContext *ctx = context->newCallContext(f, callData); if (!f->strictMode && !callData->thisObject.isObject()) { @@ -511,6 +519,9 @@ ReturnedValue SimpleScriptFunction::construct(Managed *that, CallData *callData) { ExecutionEngine *v4 = that->engine(); Scope scope(v4); + if (scope.hasException()) + return Encode::undefined(); + Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that)); InternalClass *ic = v4->objectClass; @@ -536,6 +547,9 @@ ReturnedValue SimpleScriptFunction::call(Managed *that, CallData *callData) { ExecutionEngine *v4 = that->engine(); Scope scope(v4); + if (scope.hasException()) + return Encode::undefined(); + Scoped<SimpleScriptFunction> f(scope, static_cast<SimpleScriptFunction *>(that)); void *stackSpace = alloca(requiredMemoryForExecutionContectSimple(f)); @@ -576,6 +590,9 @@ ReturnedValue BuiltinFunction::call(Managed *that, CallData *callData) BuiltinFunction *f = static_cast<BuiltinFunction *>(that); ExecutionEngine *v4 = f->engine(); Scope scope(v4); + if (scope.hasException()) + return Encode::undefined(); + ExecutionContext *context = v4->current; SimpleCallContext ctx; @@ -594,6 +611,8 @@ ReturnedValue IndexedBuiltinFunction::call(Managed *that, CallData *callData) ExecutionEngine *v4 = f->engine(); ExecutionContext *context = v4->current; Scope scope(v4); + if (scope.hasException()) + return Encode::undefined(); SimpleCallContext ctx; ctx.initSimpleCallContext(f->scope->engine); @@ -643,6 +662,8 @@ ReturnedValue BoundFunction::call(Managed *that, CallData *dd) { BoundFunction *f = static_cast<BoundFunction *>(that); Scope scope(f->scope->engine); + if (scope.hasException()) + return Encode::undefined(); ScopedCallData callData(scope, f->boundArgs.size() + dd->argc); callData->thisObject = f->boundThis; @@ -655,6 +676,9 @@ ReturnedValue BoundFunction::construct(Managed *that, CallData *dd) { BoundFunction *f = static_cast<BoundFunction *>(that); Scope scope(f->scope->engine); + if (scope.hasException()) + return Encode::undefined(); + ScopedCallData callData(scope, f->boundArgs.size() + dd->argc); memcpy(callData->args, f->boundArgs.constData(), f->boundArgs.size()*sizeof(SafeValue)); memcpy(callData->args + f->boundArgs.size(), dd->args, dd->argc*sizeof(SafeValue)); diff --git a/src/qml/jsruntime/qv4globalobject.cpp b/src/qml/jsruntime/qv4globalobject.cpp index 084b508b52..fca49308cc 100644 --- a/src/qml/jsruntime/qv4globalobject.cpp +++ b/src/qml/jsruntime/qv4globalobject.cpp @@ -469,6 +469,10 @@ ReturnedValue GlobalFunctions::method_parseInt(SimpleCallContext *ctx) // [15.1.2.2] step by step: String *inputString = string->toString(ctx); // 1 QString trimmed = inputString->toQString().trimmed(); // 2 + + if (ctx->engine->hasException) + return Encode::undefined(); + const QChar *pos = trimmed.constData(); const QChar *end = pos + trimmed.length(); diff --git a/src/qml/jsruntime/qv4jsonobject.cpp b/src/qml/jsruntime/qv4jsonobject.cpp index 721843afba..5a8acf803c 100644 --- a/src/qml/jsruntime/qv4jsonobject.cpp +++ b/src/qml/jsruntime/qv4jsonobject.cpp @@ -801,7 +801,7 @@ QString Stringify::JO(ObjectRef o) name = it.nextPropertyNameAsString(val); if (name->isNull()) break; - QString key = name->toQStringNoThrow(); + QString key = name->toQString(); QString member = makeMember(key, val); if (!member.isEmpty()) partial += member; @@ -951,7 +951,7 @@ ReturnedValue JsonObject::method_stringify(SimpleCallContext *ctx) ScopedValue arg0(scope, ctx->argument(0)); QString result = stringify.Str(QString(), arg0); - if (result.isEmpty()) + if (result.isEmpty() || scope.engine->hasException) return Encode::undefined(); return ctx->engine->newString(result)->asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp index dd13f493f7..098afa8161 100644 --- a/src/qml/jsruntime/qv4numberobject.cpp +++ b/src/qml/jsruntime/qv4numberobject.cpp @@ -177,10 +177,9 @@ ReturnedValue NumberPrototype::method_toLocaleString(SimpleCallContext *ctx) { Scope scope(ctx); ScopedValue v(scope, thisNumberValue(ctx)); + ScopedString str(scope, v->toString(ctx)); if (ctx->engine->hasException) return Encode::undefined(); - - ScopedString str(scope, v->toString(ctx)); return str.asReturnedValue(); } diff --git a/src/qml/jsruntime/qv4object.cpp b/src/qml/jsruntime/qv4object.cpp index ca02d6703a..3277ea96ab 100644 --- a/src/qml/jsruntime/qv4object.cpp +++ b/src/qml/jsruntime/qv4object.cpp @@ -147,6 +147,9 @@ ReturnedValue Object::getValue(const ValueRef thisObject, const Property *p, Pro void Object::putValue(Property *pd, PropertyAttributes attrs, const ValueRef value) { + if (internalClass->engine->hasException) + return; + if (attrs.isAccessor()) { if (pd->set) { Scope scope(pd->set->engine()); @@ -689,6 +692,9 @@ ReturnedValue Object::internalGetIndexed(uint index, bool *hasProperty) // Section 8.12.5 void Object::internalPut(const StringRef name, const ValueRef value) { + if (internalClass->engine->hasException) + return; + uint idx = name->asArrayIndex(); if (idx != UINT_MAX) return putIndexed(idx, value); @@ -773,6 +779,9 @@ void Object::internalPut(const StringRef name, const ValueRef value) void Object::internalPutIndexed(uint index, const ValueRef value) { + if (internalClass->engine->hasException) + return; + Property *pd = 0; PropertyAttributes attrs; @@ -842,6 +851,9 @@ void Object::internalPutIndexed(uint index, const ValueRef value) // Section 8.12.7 bool Object::internalDeleteProperty(const StringRef name) { + if (internalClass->engine->hasException) + return false; + uint idx = name->asArrayIndex(); if (idx != UINT_MAX) return deleteIndexedProperty(idx); @@ -865,6 +877,9 @@ bool Object::internalDeleteProperty(const StringRef name) bool Object::internalDeleteIndexedProperty(uint index) { + if (internalClass->engine->hasException) + return false; + uint pidx = propertyIndexFromArrayIndex(index); if (pidx == UINT_MAX) return true; @@ -1121,12 +1136,16 @@ ReturnedValue Object::arrayIndexOf(const ValueRef v, uint fromIndex, uint endInd for (uint i = fromIndex; i < endIndex; ++i) { bool exists; value = o->getIndexed(i, &exists); + if (scope.hasException()) + return Encode::undefined(); if (exists && __qmljs_strict_equal(value, v)) return Encode(i); } } else if (sparseArray) { for (SparseArrayNode *n = sparseArray->lowerBound(fromIndex); n != sparseArray->end() && n->key() < endIndex; n = n->nextNode()) { value = o->getValue(arrayData + n->value, arrayAttributes ? arrayAttributes[n->value] : Attr_Data); + if (scope.hasException()) + return Encode::undefined(); if (__qmljs_strict_equal(value, v)) return Encode(n->key()); } @@ -1139,6 +1158,8 @@ ReturnedValue Object::arrayIndexOf(const ValueRef v, uint fromIndex, uint endInd while (pd < end) { if (!pd->value.isEmpty()) { value = o->getValue(pd, arrayAttributes ? arrayAttributes[pd - arrayData] : Attr_Data); + if (scope.hasException()) + return Encode::undefined(); if (__qmljs_strict_equal(value, v)) return Encode((uint)(pd - arrayData)); } @@ -1437,7 +1458,7 @@ QStringList ArrayObject::toQStringList() const uint32_t length = arrayLength(); for (uint32_t i = 0; i < length; ++i) { v = const_cast<ArrayObject *>(this)->getIndexed(i); - result.append(v->toString(engine->current)->toQString()); + result.append(v->toQStringNoThrow()); } return result; } diff --git a/src/qml/jsruntime/qv4objectproto.cpp b/src/qml/jsruntime/qv4objectproto.cpp index 061487f8af..c8202a5bad 100644 --- a/src/qml/jsruntime/qv4objectproto.cpp +++ b/src/qml/jsruntime/qv4objectproto.cpp @@ -158,6 +158,8 @@ ReturnedValue ObjectPrototype::method_getOwnPropertyDescriptor(SimpleCallContext ScopedValue v(scope, ctx->argument(1)); Scoped<String> name(scope, v->toString(ctx)); + if (scope.hasException()) + return Encode::undefined(); PropertyAttributes attrs; Property *desc = O->__getOwnProperty__(name, &attrs); return fromPropertyDescriptor(ctx, desc, attrs); diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index a581e6bc69..acdfc1ba52 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -627,7 +627,7 @@ void QObjectWrapper::put(Managed *m, const StringRef name, const ValueRef value) QObjectWrapper *that = static_cast<QObjectWrapper*>(m); ExecutionEngine *v4 = m->engine(); - if (QQmlData::wasDeleted(that->m_object)) + if (v4->hasException || QQmlData::wasDeleted(that->m_object)) return; QQmlContextData *qmlContext = QV4::QmlContextWrapper::callingContext(v4); diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index 8bcddcce0a..4f0f07377f 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -258,6 +258,8 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData) QString pattern; if (!r->isUndefined()) pattern = r->toString(ctx)->toQString(); + if (scope.hasException()) + return Encode::undefined(); bool global = false; bool ignoreCase = false; @@ -265,6 +267,8 @@ ReturnedValue RegExpCtor::construct(Managed *m, CallData *callData) if (!f->isUndefined()) { f = __qmljs_to_string(f, ctx); QString str = f->stringValue()->toQString(); + if (scope.hasException()) + return Encode::undefined(); for (int i = 0; i < str.length(); ++i) { if (str.at(i) == QChar('g') && !global) { global = true; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index dbbccdea70..5678294115 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -478,8 +478,6 @@ void __qmljs_set_property(ExecutionContext *ctx, const ValueRef object, const St { Scope scope(ctx); ScopedObject o(scope, object->toObject(ctx)); - if (scope.engine->hasException) - return; o->put(name, value); } @@ -571,8 +569,6 @@ void __qmljs_set_element(ExecutionContext *ctx, const ValueRef object, const Val } ScopedString name(scope, index->toString(ctx)); - if (scope.hasException()) - return; o->put(name, value); } diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index f6feb2f170..5a42c7fe35 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -231,6 +231,9 @@ public: void containerPutIndexed(uint index, const QV4::ValueRef value) { + if (internalClass->engine->hasException) + return; + /* Qt containers have int (rather than uint) allowable indexes. */ if (index > INT_MAX) { generateWarning(engine()->current, QLatin1String("Index out of range during indexed set")); diff --git a/src/qml/jsruntime/qv4string.cpp b/src/qml/jsruntime/qv4string.cpp index fd366d26ac..bd4e2b16b0 100644 --- a/src/qml/jsruntime/qv4string.cpp +++ b/src/qml/jsruntime/qv4string.cpp @@ -178,6 +178,8 @@ ReturnedValue String::getIndexed(Managed *m, uint index, bool *hasProperty) void String::put(Managed *m, const StringRef name, const ValueRef value) { Scope scope(m->engine()); + if (scope.hasException()) + return; ScopedString that(scope, static_cast<String *>(m)); Scoped<Object> o(scope, that->engine()->newStringObject(that)); o->put(name, value); @@ -186,6 +188,9 @@ void String::put(Managed *m, const StringRef name, const ValueRef value) void String::putIndexed(Managed *m, uint index, const ValueRef value) { Scope scope(m->engine()); + if (scope.hasException()) + return; + ScopedString that(scope, static_cast<String *>(m)); Scoped<Object> o(scope, that->engine()->newStringObject(that)); o->putIndexed(index, value); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index 36d1433665..f36c7d84a4 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -597,15 +597,16 @@ ReturnedValue StringPrototype::method_search(SimpleCallContext *ctx) { Scope scope(ctx); QString string = getThisString(ctx); + ScopedValue regExpValue(scope, ctx->argument(0)); if (scope.engine->hasException) return Encode::undefined(); - - ScopedValue regExpValue(scope, ctx->argument(0)); Scoped<RegExpObject> regExp(scope, regExpValue->as<RegExpObject>()); if (!regExp) { ScopedCallData callData(scope, 1); callData->args[0] = regExpValue; regExpValue = ctx->engine->regExpCtor.asFunctionObject()->construct(callData); + if (scope.engine->hasException) + return Encode::undefined(); regExp = regExpValue->as<RegExpObject>(); Q_ASSERT(regExp); } diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index a187b17a08..d3bcf6d3fd 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -281,6 +281,8 @@ void QmlContextWrapper::put(Managed *m, const StringRef name, const ValueRef val { ExecutionEngine *v4 = m->engine(); QV4::Scope scope(v4); + if (scope.hasException()) + return; QV4::Scoped<QmlContextWrapper> wrapper(scope, m->as<QmlContextWrapper>()); if (!wrapper) { v4->current->throwTypeError(); diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index ca53d1a53d..3fb3d19270 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -229,6 +229,8 @@ void QmlTypeWrapper::put(Managed *m, const StringRef name, const ValueRef value) { QmlTypeWrapper *w = m->as<QmlTypeWrapper>(); QV4::ExecutionEngine *v4 = m->engine(); + if (v4->hasException) + return; if (!w) { v4->current->throwTypeError(); return; diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index e892fb2c0c..6c9f90cada 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -334,6 +334,9 @@ void QmlValueTypeWrapper::put(Managed *m, const StringRef name, const ValueRef v { ExecutionEngine *v4 = m->engine(); Scope scope(v4); + if (scope.hasException()) + return; + Scoped<QmlValueTypeWrapper> r(scope, m->as<QmlValueTypeWrapper>()); if (!r) { v4->current->throwTypeError(); diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 5abab8500b..2b2504daf2 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -3194,6 +3194,9 @@ void QQuickJSContext2DPixelData::putIndexed(QV4::Managed *m, uint index, const Q { QV4::ExecutionEngine *v4 = m->engine(); QV4::Scope scope(v4); + if (scope.hasException()) + return; + QV4::Scoped<QQuickJSContext2DPixelData> r(scope, m->as<QQuickJSContext2DPixelData>()); if (!r) { v4->current->throwTypeError(); |