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 /src/qml/jsruntime/qv4arrayobject.cpp | |
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]>
Diffstat (limited to 'src/qml/jsruntime/qv4arrayobject.cpp')
-rw-r--r-- | src/qml/jsruntime/qv4arrayobject.cpp | 54 |
1 files changed, 44 insertions, 10 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); } |