diff options
author | Gunnar Sletta <gunnar.sletta@jollamobile.com> | 2014-02-19 21:38:17 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-20 23:08:01 +0100 |
commit | f158fa7feaa5d9fc2ae17aa16853acbbb947443a (patch) | |
tree | fb78a51d5310786f4531cf9127721bb2b772f90d /src/quick/items/qquickshadereffect.cpp | |
parent | 43f983350a548b1b663ea07a0e87e4cc58834214 (diff) |
Prevent dangling pointer in QQuickShaderEffectSource.
Task-number: QTBUG-36931
Change-Id: Idb584a8703a8d93d2cbcd3feb7942476dc165a59
Reviewed-by: Mitch Curtis <mitch.curtis@digia.com>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'src/quick/items/qquickshadereffect.cpp')
-rw-r--r-- | src/quick/items/qquickshadereffect.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index 9a20703f18..e57b7abddc 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -478,6 +478,19 @@ void QQuickShaderEffectCommon::sourceDestroyed(QObject *object) } } +static bool qquick_uniqueInUniformData(QQuickItem *source, const QVector<QQuickShaderEffectMaterial::UniformData> *uniformData, int typeToSkip, int indexToSkip) +{ + for (int s=0; s<QQuickShaderEffectMaterialKey::ShaderTypeCount; ++s) { + for (int i=0; i<uniformData[s].size(); ++i) { + if (s == typeToSkip && i == indexToSkip) + continue; + const QQuickShaderEffectMaterial::UniformData &d = uniformData[s][i]; + if (d.specialType == QQuickShaderEffectMaterial::UniformData::Sampler && qvariant_cast<QObject *>(d.value) == source) + return false; + } + } + return true; +} void QQuickShaderEffectCommon::propertyChanged(QQuickItem *item, int mappedId, bool *textureProviderChanged) @@ -490,7 +503,13 @@ void QQuickShaderEffectCommon::propertyChanged(QQuickItem *item, int mappedId, if (source) { if (item->window()) QQuickItemPrivate::get(source)->derefWindow(); - QObject::disconnect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*))); + + // QObject::disconnect() will disconnect all matching connections. If the same + // source has been attached to two separate samplers, then changing one of them + // would trigger both to be disconnected. Without the connection we'll end up + // with a dangling pointer in the uniformData. + if (qquick_uniqueInUniformData(source, uniformData, shaderType, index)) + QObject::disconnect(source, SIGNAL(destroyed(QObject*)), item, SLOT(sourceDestroyed(QObject*))); } d.value = item->property(d.name.constData()); |