diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/qml/qqmlcomponent.cpp | 28 | ||||
-rw-r--r-- | src/qml/qml/qqmlcomponent_p.h | 4 |
2 files changed, 30 insertions, 2 deletions
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 768e80f82f..5473290633 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -63,10 +63,15 @@ #include <QStack> #include <QStringList> +#include <QThreadStorage> #include <QtCore/qdebug.h> #include <qqmlinfo.h> #include "qqmlmemoryprofiler_p.h" +namespace { + QThreadStorage<int> creationDepth; +} + QT_BEGIN_NAMESPACE class QQmlComponentExtension : public QV8Engine::Deletable @@ -772,7 +777,8 @@ QObject *QQmlComponent::create(QQmlContext *context) context = d->engine->rootContext(); QObject *rv = beginCreate(context); - completeCreate(); + if (rv) + completeCreate(); return rv; } @@ -840,6 +846,16 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context) return 0; } + // Do not create infinite recursion in object creation + static const int maxCreationDepth = 10; + if (++creationDepth.localData() >= maxCreationDepth) { + qWarning("QQmlComponent: Component creation is recursing - aborting"); + --creationDepth.localData(); + return 0; + } + Q_ASSERT(creationDepth.localData() >= 1); + depthIncreased = true; + QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine); if (enginePriv->inProgressCreations == 0) { @@ -864,6 +880,10 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context) ddata->indestructible = true; ddata->explicitIndestructibleSet = true; ddata->rootObjectInCreation = false; + } else { + Q_ASSERT(creationDepth.localData() >= 1); + --creationDepth.localData(); + depthIncreased = false; } if (enginePriv->isDebugging && rv) { @@ -936,6 +956,12 @@ void QQmlComponentPrivate::completeCreate() delete profiler; profiler = 0; } + + if (depthIncreased) { + Q_ASSERT(creationDepth.localData() >= 1); + --creationDepth.localData(); + depthIncreased = false; + } } QQmlComponentAttached::QQmlComponentAttached(QObject *parent) diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index 9e220b5e95..f5589b9003 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -84,7 +84,8 @@ class Q_QML_PRIVATE_EXPORT QQmlComponentPrivate : public QObjectPrivate, public Q_DECLARE_PUBLIC(QQmlComponent) public: - QQmlComponentPrivate() : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0), profiler(0) {} + QQmlComponentPrivate() + : typeData(0), progress(0.), start(-1), cc(0), engine(0), creationContext(0), profiler(0), depthIncreased(false) {} void loadUrl(const QUrl &newUrl, QQmlComponent::CompilationMode mode = QQmlComponent::PreferSynchronous); @@ -120,6 +121,7 @@ public: QQmlEngine *engine; QQmlGuardedContextData creationContext; QQmlObjectCreatingProfiler *profiler; + bool depthIncreased; void clear(); |