diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2015-04-30 15:04:41 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2015-04-30 15:28:22 +0300 |
commit | f271d85b865cb5e82b50a29f91d2cabbbede6a9a (patch) | |
tree | 4811571c2de75cc04bf3dbf15489a26a013a8b80 /source/blender/windowmanager | |
parent | d1c98520f7b792d5f2f1f2d1eb51d08d172e2e22 (diff) |
Fix T44439: outliner's treestore could keep invalid ID pointers, could crash on undo due to invalid mem access.
We cannot nuke treestore in readfile's `blo_lib_link_screen_restore()`, because this will
destroy all UI-state data (like opened/closed items, etc.).
Since we cannot know for sure whether an ID pointer from tselem->id is valid here, we
have to ensure they are never invalid, i.e. to always set them to NULL when we delete them.
To do so, this commit uses a similar approach as what already exists for ID references
in WM notifiers - it extends `free_notifier_reference_cb()` to also nullify those IDs in
all outliners.
Note that some ID types are not used(shown) by outliner currently, so `TREESTORE_ID_TYPE` macro
was added, that checks whether an ID is possibly used by outliner. Avoids a few searches
in whole tree whene deleting some IDs.
Reviewers: campbellbarton, sergey
Maniphest Tasks: T44439
Differential Revision: https://developer.blender.org/D1272
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index e2b8598b4fe..c883b37f6c5 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -63,6 +63,7 @@ #include "ED_fileselect.h" #include "ED_info.h" +#include "ED_outliner.h" #include "ED_screen.h" #include "ED_view3d.h" #include "ED_util.h" @@ -217,6 +218,8 @@ void WM_main_remove_notifier_reference(const void *reference) { Main *bmain = G.main; wmWindowManager *wm = bmain->wm.first; + bScreen *sc; + if (wm) { wmNotifier *note, *note_next; @@ -230,6 +233,22 @@ void WM_main_remove_notifier_reference(const void *reference) } } } + + for (sc = bmain->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_OUTLINER) { + SpaceOops *so = (SpaceOops *)sl; + + ED_outliner_id_unref(so, (ID *)reference); + } + } + } + } } static void wm_notifier_clear(wmNotifier *note) |