diff options
author | Julian Eisel <julian@blender.org> | 2020-11-02 23:47:08 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-11-03 02:00:41 +0300 |
commit | a750acab78cf38ca8f010c4ac81ec948faa79dd5 (patch) | |
tree | 6603e8747261895ff1b9dc9768cf47be202fefd3 /source/blender | |
parent | 9cfcc273194e6e9706fefaac739b3d73eca2f62f (diff) |
Fix possible use-after-free when closing Blender with File Browser open
I think there wasn't actually any issue currently, but only by luck. We still
passed around and NULL-checked a pointer to freed memory (the file operator,
`SpaceFile.op`) which is easy to break and should be avoided.
Noticed while testing D8598.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/include/ED_fileselect.h | 4 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 18 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 13 |
3 files changed, 35 insertions, 0 deletions
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 341f97943a5..84808416074 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -35,6 +35,7 @@ struct SpaceFile; struct bContext; struct bScreen; struct uiBlock; +struct wmOperator; struct wmWindow; struct wmWindowManager; @@ -145,6 +146,9 @@ void ED_fileselect_window_params_get(const struct wmWindow *win, int win_size[2], bool *is_maximized); +struct ScrArea *ED_fileselect_handler_area_find(const struct wmWindow *win, + const struct wmOperator *file_operator); + int ED_path_extension_type(const char *path); int ED_file_extension_icon(const char *path); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 42b2806814b..5d90403937a 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -61,6 +61,7 @@ #include "BLF_api.h" #include "ED_fileselect.h" +#include "ED_screen.h" #include "WM_api.h" #include "WM_types.h" @@ -1050,3 +1051,20 @@ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) params->rename_flag = 0; } } + +ScrArea *ED_fileselect_handler_area_find(const wmWindow *win, const wmOperator *file_operator) +{ + bScreen *screen = WM_window_get_active_screen(win); + + ED_screen_areas_iter (win, screen, area) { + if (area->spacetype == SPACE_FILE) { + SpaceFile *sfile = area->spacedata.first; + + if (sfile->op == file_operator) { + return area; + } + } + } + + return NULL; +} diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 4f2be59eb1a..a6b8eb9d3fd 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1731,8 +1731,21 @@ void WM_event_remove_handlers(bContext *C, ListBase *handlers) BLI_assert(handler_base->type != 0); if (handler_base->type == WM_HANDLER_TYPE_OP) { wmEventHandler_Op *handler = (wmEventHandler_Op *)handler_base; + if (handler->op) { wmWindow *win = CTX_wm_window(C); + + if (handler->is_fileselect) { + /* Exit File Browsers refering to this handler/operator. */ + LISTBASE_FOREACH (wmWindow *, temp_win, &wm->windows) { + ScrArea *file_area = ED_fileselect_handler_area_find(temp_win, handler->op); + if (!file_area) { + continue; + } + ED_area_exit(C, file_area); + } + } + if (handler->op->type->cancel) { ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); |