From f25aec1b38bf208a34e0aabefae5e05ca265ecd3 Mon Sep 17 00:00:00 2001 From: Federico Perini Date: Mon, 6 Oct 2025 14:32:59 +0200 Subject: [PATCH] Avoid using already destroyed timers in wxOSX Check that the timer is still valid before using the associated object. This is necessary because already queued timer events are still delivered, even if wxTimer is destroyed. Closes #25871. --- src/osx/core/timer.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/osx/core/timer.cpp b/src/osx/core/timer.cpp index ba4b2e930e..1d24b41954 100644 --- a/src/osx/core/timer.cpp +++ b/src/osx/core/timer.cpp @@ -24,11 +24,17 @@ struct wxOSXTimerInfo CFRunLoopTimerRef m_timerRef; }; -void wxProcessTimer(CFRunLoopTimerRef WXUNUSED(theTimer), void *data) +void wxProcessTimer(CFRunLoopTimerRef theTimer, void *data) { if ( data == nullptr ) return; + // CFRunLoop can fire timer callbacks after CFRunLoopTimerInvalidate() + // has been called (e.g., if the callback was already queued when Stop() was called). + // Verify the timer is still valid before proceeding to avoid crashes. + if ( !CFRunLoopTimerIsValid(theTimer) ) + return; + wxOSXTimerImpl* timer = (wxOSXTimerImpl*)data; if ( timer->IsOneShot() )