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.
This commit is contained in:
Julian Eisel 2020-11-02 21:47:08 +01:00
parent 9cfcc27319
commit a750acab78
Notes: blender-bot 2023-02-14 10:54:29 +01:00
Referenced by commit c32bee0099, Cleanup: Use recently added helper function to find File Browser UI data
3 changed files with 35 additions and 0 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);