forked from pool/libqt5-qtdeclarative
8f13e749d4
Update to 5.3.2 final OBS-URL: https://build.opensuse.org/request/show/249654 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtdeclarative?expand=0&rev=19
127 lines
4.4 KiB
Diff
127 lines
4.4 KiB
Diff
From 4d07bf91ed2d36aee9178ef48508c16277fbb318 Mon Sep 17 00:00:00 2001
|
|
From: Simon Hausmann <simon.hausmann@digia.com>
|
|
Date: Thu, 21 Aug 2014 16:24:54 +0200
|
|
Subject: [PATCH 5/6] 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>
|
|
---
|
|
src/qml/jsruntime/qv4objectiterator.cpp | 40 +++++++++++++++++++++++++--------
|
|
src/qml/jsruntime/qv4objectiterator_p.h | 11 ++++-----
|
|
2 files changed, 37 insertions(+), 14 deletions(-)
|
|
|
|
diff --git a/src/qml/jsruntime/qv4objectiterator.cpp b/src/qml/jsruntime/qv4objectiterator.cpp
|
|
index e5f693c..0efd304 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 c87f284..5ead1f5 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(); }
|
|
|
|
--
|
|
2.1.0
|
|
|