From a1f10b10b61a76ffe7b06aba030dd0706cad9969 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Aug 2022 14:58:54 +1000 Subject: Fix freed memory access checking events with debug builds Pressing escape when rendering a viewport animation would access the freed even and crash (with ASAN enabled). Always check the context's window before the event as this is a signal a file was loaded or the window was closed (and it's events freed). --- .../windowmanager/intern/wm_event_system.cc | 31 +++++++++++++--------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_event_system.cc b/source/blender/windowmanager/intern/wm_event_system.cc index 5e7fe4678f6..895bab8ed89 100644 --- a/source/blender/windowmanager/intern/wm_event_system.cc +++ b/source/blender/windowmanager/intern/wm_event_system.cc @@ -667,14 +667,23 @@ static int wm_event_always_pass(const wmEvent *event) * Debug only sanity check for the return value of event handlers. Checks that "always pass" events * don't cause non-passing handler return values, and thus actually pass. * - * Can't be executed if the handler just loaded a file (typically identified by `CTX_wm_window(C)` - * returning `nullptr`), because the event will have been freed then. + * \param C: Pass in the context to check if it's "window" was cleared. + * The event check can't be executed if the handler just loaded a file or closed the window. + * (typically identified by `CTX_wm_window(C)` returning null), + * because the event will have been freed then. + * When null, always check the event (assume the caller knows the event was not freed). */ -BLI_INLINE void wm_event_handler_return_value_check(const wmEvent *event, const int action) +BLI_INLINE void wm_event_handler_return_value_check(const bContext *C, + const wmEvent *event, + const int action) { - BLI_assert_msg(!wm_event_always_pass(event) || (action != WM_HANDLER_BREAK), - "Return value for events that should always pass should never be BREAK."); - UNUSED_VARS_NDEBUG(event, action); +#ifndef NDEBUG + if (C == nullptr || CTX_wm_window(C)) { + BLI_assert_msg(!wm_event_always_pass(event) || (action != WM_HANDLER_BREAK), + "Return value for events that should always pass should never be BREAK."); + } +#endif + UNUSED_VARS_NDEBUG(C, event, action); } /** \} */ @@ -3101,7 +3110,7 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis int action = WM_HANDLER_CONTINUE; if (handlers == nullptr) { - wm_event_handler_return_value_check(event, action); + wm_event_handler_return_value_check(C, event, action); return action; } @@ -3267,9 +3276,7 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis } /* Do some extra sanity checking before returning the action. */ - if (CTX_wm_window(C) != nullptr) { - wm_event_handler_return_value_check(event, action); - } + wm_event_handler_return_value_check(C, event, action); return action; } @@ -3440,7 +3447,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) } } - wm_event_handler_return_value_check(event, action); + wm_event_handler_return_value_check(C, event, action); return action; } @@ -3717,7 +3724,7 @@ static int wm_event_do_handlers_area_regions(bContext *C, wmEvent *event, ScrAre action |= wm_event_do_region_handlers(C, event, region); } - wm_event_handler_return_value_check(event, action); + wm_event_handler_return_value_check(C, event, action); return action; } -- cgit v1.2.3