diff options
author | Jian Liang <jianliang79@gmail.com> | 2012-09-21 02:48:00 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-09-27 14:59:15 (GMT) |
commit | 6c3275d17e3134497873b9ae10b6471656170da0 (patch) | |
tree | 4bbcea4d0094e33abe8725660934226ba644e9d1 | |
parent | 8cc85123aee262f9ac061908aff0360247077075 (diff) | |
download | Qt-6c3275d17e3134497873b9ae10b6471656170da0.zip Qt-6c3275d17e3134497873b9ae10b6471656170da0.tar.gz Qt-6c3275d17e3134497873b9ae10b6471656170da0.tar.bz2 |
Avoid crash caused by drag and drop and winId()
Task-number: QTBUG-27263
QWExtra object pointer is not guaranteed to be valid in
QWidget::unregisterOldDnd() since commit
f6bf4b2baa91e55f40596bf3f2823b119fdfa5e0. To avoid crash we have to check
QWExtra object pointer of the native parent widget before access it, and
if the pointer is not valid we should check its native parent widget
recursively.
Change-Id: I764fea4a0826cff751dd74a0fb67e0d2971c1d49
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
-rw-r--r-- | src/gui/kernel/qwidget_win.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index d15a447..c965871 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -1799,18 +1799,28 @@ void QWidgetPrivate::unregisterOleDnd(QWidget *widget, QOleDropTarget *dropTarge Q_ASSERT(widget->testAttribute(Qt::WA_WState_Created)); if (!widget->internalWinId()) { QWidget *nativeParent = widget->nativeParentWidget(); - Q_ASSERT(nativeParent); - QWExtra *nativeExtra = nativeParent->d_func()->extra; - Q_ASSERT(nativeExtra); - nativeExtra->oleDropWidgets.removeAll(widget); - nativeExtra->oleDropWidgets.removeAll(static_cast<QWidget *>(0)); - if (nativeExtra->oleDropWidgets.isEmpty() && nativeExtra->dropTarget + while (nativeParent) { + QWExtra *nativeExtra = nativeParent->d_func()->extra; + if (!nativeExtra) { + nativeParent = nativeParent->nativeParentWidget(); + continue; + } + + const int removeCounter = nativeExtra->oleDropWidgets.removeAll(widget); + nativeExtra->oleDropWidgets.removeAll(static_cast<QWidget *>(0)); + if (nativeExtra->oleDropWidgets.isEmpty() && nativeExtra->dropTarget && !nativeParent->testAttribute(Qt::WA_DropSiteRegistered)) { #ifndef Q_OS_WINCE - CoLockObjectExternal(nativeExtra->dropTarget, false, true); + CoLockObjectExternal(nativeExtra->dropTarget, false, true); #endif - RevokeDragDrop(nativeParent->internalWinId()); - nativeExtra->dropTarget = 0; + RevokeDragDrop(nativeParent->internalWinId()); + nativeExtra->dropTarget = 0; + } + + if (removeCounter) + break; + + nativeParent = nativeParent->nativeParentWidget(); } } else { #ifndef Q_OS_WINCE |