From cdaea1696416bb2c6e1c12519c5d9d6b8bec1969 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Mar 2017 18:58:27 -0700 Subject: Protect better against timer ID replacement Timer IDs have been reused since Qt 4.5 or thereabouts, so just checking if the timer ID is in the timer dictionary is an incorrect check: our timer may have been deleted and replaced by another with the same ID. Instead of deleting the WinTimerInfo object, let's just mark it as unregistered by setting timerId to -1 and cooperate in deleting at the appropriate places. Since unregisterTimer skips deleting if inTimerEvent is true, the appropriate places are everywhere that set inTimerEvent to true. Change-Id: I057e93314e41372ae7a5ff93c467767c8a6d92ea Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- src/corelib/kernel/qeventdispatcher_win.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/corelib/kernel/qeventdispatcher_win.cpp') diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 88dbe8e4f7..fd9d41647d 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -406,7 +406,9 @@ void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t) } else if (internalHwnd) { KillTimer(internalHwnd, t->timerId); } - delete t; + t->timerId = -1; + if (!t->inTimerEvent) + delete t; } void QEventDispatcherWin32Private::sendTimerEvent(int timerId) @@ -423,8 +425,9 @@ void QEventDispatcherWin32Private::sendTimerEvent(int timerId) QCoreApplication::sendEvent(t->obj, &e); // timer could have been removed - t = timerDict.value(timerId); - if (t) { + if (t->timerId == -1) { + delete t; + } else { t->inTimerEvent = false; } } @@ -1012,8 +1015,10 @@ bool QEventDispatcherWin32::event(QEvent *e) QTimerEvent te(zte->timerId()); QCoreApplication::sendEvent(t->obj, &te); - t = d->timerDict.value(zte->timerId()); - if (t) { + // timer could have been removed + if (t->timerId == -1) { + delete t; + } else { if (t->interval == 0 && t->inTimerEvent) { // post the next zero timer event as long as the timer was not restarted QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId())); -- cgit v1.2.3