aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@digia.com>2014-11-06 14:40:37 +0100
committerUlf Hermann <ulf.hermann@digia.com>2014-11-06 17:52:26 +0100
commita4877338826381d454dfdae74242a007b3aac9e0 (patch)
treed62e0d19b36fd463b11ea5b11cadac59375fbc74
parent61dd293a145a3881c6ff4a223121f655f1f8d0bc (diff)
Avoid stack overflow when destroying InternalClass
If there are deep object hierarchies connected to an InternalClass the recursive nature of the destroy() method could lead to a stack overflow. By changing the recursion into an iteration this is avoided. Change-Id: I6667f268a366749c2dbc5f7147882388f192a9c5 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/jsruntime/qv4internalclass.cpp35
1 files changed, 17 insertions, 18 deletions
diff --git a/src/qml/jsruntime/qv4internalclass.cpp b/src/qml/jsruntime/qv4internalclass.cpp
index a59c3892a1..bb22e30ac1 100644
--- a/src/qml/jsruntime/qv4internalclass.cpp
+++ b/src/qml/jsruntime/qv4internalclass.cpp
@@ -412,25 +412,24 @@ InternalClass *InternalClass::frozen()
void InternalClass::destroy()
{
- if (!engine)
- return;
- engine = 0;
-
- propertyTable.~PropertyHash();
- nameMap.~SharedInternalClassData<String *>();
- propertyData.~SharedInternalClassData<PropertyAttributes>();
+ QList<InternalClass *> destroyStack;
+ destroyStack.append(this);
- if (m_sealed)
- m_sealed->destroy();
-
- if (m_frozen)
- m_frozen->destroy();
-
- for (QHash<Transition, InternalClass *>::ConstIterator it = transitions.begin(), end = transitions.end();
- it != end; ++it)
- it.value()->destroy();
-
- transitions.clear();
+ while (!destroyStack.isEmpty()) {
+ InternalClass *next = destroyStack.takeLast();
+ if (!next->engine)
+ continue;
+ next->engine = 0;
+ next->propertyTable.~PropertyHash();
+ next->nameMap.~SharedInternalClassData<String *>();
+ next->propertyData.~SharedInternalClassData<PropertyAttributes>();
+ if (next->m_sealed)
+ destroyStack.append(next->m_sealed);
+ if (next->m_frozen)
+ destroyStack.append(next->m_frozen);
+ destroyStack.append(next->transitions.values());
+ next->transitions.clear();
+ }
}
struct InternalClassPoolVisitor