aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-08-21 16:24:54 +0200
committerAlbert Astals Cid <aacid@kde.org>2014-09-11 10:04:26 +0200
commit4d07bf91ed2d36aee9178ef48508c16277fbb318 (patch)
tree4606637c834c43ea042d5c0250644b4d61b3c626
parentf7c3035fa1d965dceb36892122683a5ceb6cab89 (diff)
Fix crash with foreach on arguments object
We call fullyCreate() on the arguments object when it's initialized on an foreach iterator. That itself however might trigger an allocation, which in turn might collect the ForEachIteratorObject, which is missing a "ProtectThis" in its constructor. Change-Id: Ib8f7e39201e727cde91cbbe8a82cba78aa980f0d Task-number: QTBUG-40844 Reviewed-by: Albert Astals Cid <albert.astals@canonical.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/jsruntime/qv4objectiterator.cpp40
-rw-r--r--src/qml/jsruntime/qv4objectiterator_p.h11
2 files changed, 37 insertions, 14 deletions
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
index e5f693c323..0efd3045ba 100644
--- a/src/qml/jsruntime/qv4objectiterator.cpp
+++ b/src/qml/jsruntime/qv4objectiterator.cpp
@@ -54,13 +54,7 @@ ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef
, memberIndex(0)
, flags(flags)
{
- object = o.getPointer();
- current = o.getPointer();
-
- if (!!object && object->asArgumentsObject()) {
- Scope scope(object->engine());
- Scoped<ArgumentsObject> (scope, object->asReturnedValue())->fullyCreate();
- }
+ init(o);
}
ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
@@ -71,8 +65,26 @@ ObjectIterator::ObjectIterator(Scope &scope, const ObjectRef o, uint flags)
, memberIndex(0)
, flags(flags)
{
- object = o;
- current = o;
+ init(o);
+}
+
+ObjectIterator::ObjectIterator(Value *scratch1, Value *scratch2, uint flags)
+ : object(ObjectRef::fromValuePointer(scratch1))
+ , current(ObjectRef::fromValuePointer(scratch2))
+ , arrayNode(0)
+ , arrayIndex(0)
+ , memberIndex(0)
+ , flags(flags)
+{
+ object = (Object*)0;
+ current = (Object*)0;
+ // Caller needs to call init!
+}
+
+void ObjectIterator::init(const ObjectRef o)
+{
+ object = o.getPointer();
+ current = o.getPointer();
if (!!object && object->asArgumentsObject()) {
Scope scope(object->engine());
@@ -194,6 +206,16 @@ ReturnedValue ObjectIterator::nextPropertyNameAsString()
DEFINE_OBJECT_VTABLE(ForEachIteratorObject);
+ForEachIteratorObject::ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
+ : Object(ctx->engine), it(workArea, workArea + 1, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain)
+{
+ Scope scope(ctx);
+ ScopedObject protectThis(scope, this);
+
+ setVTable(staticVTable());
+ it.init(o);
+}
+
void ForEachIteratorObject::markObjects(Managed *that, ExecutionEngine *e)
{
ForEachIteratorObject *o = static_cast<ForEachIteratorObject *>(that);
diff --git a/src/qml/jsruntime/qv4objectiterator_p.h b/src/qml/jsruntime/qv4objectiterator_p.h
index c87f284288..5ead1f5a23 100644
--- a/src/qml/jsruntime/qv4objectiterator_p.h
+++ b/src/qml/jsruntime/qv4objectiterator_p.h
@@ -58,6 +58,7 @@ struct ExecutionContext;
struct Property;
struct String;
struct InternalClass;
+struct ForEachIteratorObject;
struct Q_QML_EXPORT ObjectIterator
{
@@ -76,21 +77,21 @@ struct Q_QML_EXPORT ObjectIterator
ObjectIterator(Value *scratch1, Value *scratch2, const ObjectRef o, uint flags);
ObjectIterator(Scope &scope, const ObjectRef o, uint flags);
+ void init(const ObjectRef o);
void next(StringRef name, uint *index, Property *pd, PropertyAttributes *attributes = 0);
ReturnedValue nextPropertyName(ValueRef value);
ReturnedValue nextPropertyNameAsString(ValueRef value);
ReturnedValue nextPropertyNameAsString();
+private:
+ friend struct ForEachIteratorObject;
+ ObjectIterator(Value *scratch1, Value *scratch2, uint flags); // Constructor that requires calling init()
};
struct ForEachIteratorObject: Object {
V4_OBJECT
Q_MANAGED_TYPE(ForeachIteratorObject)
ObjectIterator it;
- ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o)
- : Object(ctx->engine), it(workArea, workArea + 1,
- o, ObjectIterator::EnumerableOnly|ObjectIterator::WithProtoChain) {
- setVTable(staticVTable());
- }
+ ForEachIteratorObject(ExecutionContext *ctx, const ObjectRef o);
ReturnedValue nextPropertyName() { return it.nextPropertyNameAsString(); }