diff options
author | Campbell Barton <ideasman42@gmail.com> | 2015-05-04 08:07:24 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2015-05-04 09:01:20 +0300 |
commit | 77e6a001a96b7eb3b2b1c2216a48c85c1b6906e0 (patch) | |
tree | ff2d44f3d8c661445e5d358f11e9043beadb23f0 | |
parent | 8d5e57748a777a76dbbe85d432d7d8364775713a (diff) |
Fix T44376: Buttons context, invalid data access
Removing a scene from the buttons window would crash from a Python operator.
-rw-r--r-- | source/blender/blenkernel/BKE_screen.h | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/screen.c | 13 | ||||
-rw-r--r-- | source/blender/editors/include/ED_buttons.h | 2 | ||||
-rw-r--r-- | source/blender/editors/include/ED_screen.h | 1 | ||||
-rw-r--r-- | source/blender/editors/include/ED_util.h | 2 | ||||
-rw-r--r-- | source/blender/editors/space_buttons/buttons_context.c | 26 | ||||
-rw-r--r-- | source/blender/editors/util/ed_util.c | 21 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 1 |
9 files changed, 71 insertions, 1 deletions
diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index bb764540da9..c584051708b 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -273,6 +273,9 @@ void BKE_spacedata_freelist(ListBase *lb); void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2); void BKE_spacedata_draw_locks(int set); +void BKE_spacedata_callback_id_unref_set(void (*func)(struct SpaceLink *sl, const struct ID *)); +void BKE_spacedata_id_unref(struct SpaceLink *sl, const struct ID *id); + /* area/regions */ struct ARegion *BKE_area_region_copy(struct SpaceType *st, struct ARegion *ar); void BKE_area_region_free(struct SpaceType *st, struct ARegion *ar); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 5b34504184a..c24649556fc 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -82,6 +82,7 @@ #include "BKE_paint.h" #include "BKE_rigidbody.h" #include "BKE_scene.h" +#include "BKE_screen.h" #include "BKE_sequencer.h" #include "BKE_sound.h" #include "BKE_unit.h" @@ -823,6 +824,8 @@ static void scene_unlink_space_buts(SpaceButs *sbuts, Scene *sce) if (sbuts->pinid == &sce->id) { sbuts->pinid = NULL; } + + BKE_spacedata_id_unref((SpaceLink *)sbuts, &sce->id); } void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce) diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 36fd598cc70..840e1f99f84 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -272,6 +272,19 @@ void BKE_spacedata_draw_locks(int set) } } +static void (*spacedata_id_unref_cb)(struct SpaceLink *sl, const struct ID *id) = NULL; + +void BKE_spacedata_callback_id_unref_set(void (*func)(struct SpaceLink *sl, const struct ID *)) +{ + spacedata_id_unref_cb = func; +} + +void BKE_spacedata_id_unref(struct SpaceLink *sl, const struct ID *id) +{ + if (spacedata_id_unref_cb) { + spacedata_id_unref_cb(sl, id); + } +} /* not region itself */ void BKE_area_region_free(SpaceType *st, ARegion *ar) diff --git a/source/blender/editors/include/ED_buttons.h b/source/blender/editors/include/ED_buttons.h index 64c16605dec..9a987d7618c 100644 --- a/source/blender/editors/include/ED_buttons.h +++ b/source/blender/editors/include/ED_buttons.h @@ -37,4 +37,6 @@ bool ED_texture_context_check_particles(const struct bContext *C); bool ED_texture_context_check_linestyle(const struct bContext *C); bool ED_texture_context_check_others(const struct bContext *C); +void ED_buttons_id_unref(struct SpaceButs *sbuts, const struct ID *id); + #endif /* __ED_BUTTONS_H__ */ diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 5b0b4642644..8de9a7f5f88 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -76,7 +76,6 @@ void ED_region_visible_rect(struct ARegion *ar, struct rcti *rect); void ED_spacetypes_keymap(struct wmKeyConfig *keyconf); int ED_area_header_switchbutton(const struct bContext *C, struct uiBlock *block, int yco); - /* areas */ void ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa); void ED_area_exit(struct bContext *C, struct ScrArea *sa); diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 9556c601d1f..496ce7f2c60 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -42,6 +42,8 @@ void ED_editors_exit(struct bContext *C); bool ED_editors_flush_edits(const struct bContext *C, bool for_render); +void ED_spacedata_id_unref(struct SpaceLink *sl, const struct ID *id); + /* ************** Undo ************************ */ /* undo.c */ diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index 73091e7f261..b00a2c54ff9 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -59,6 +59,7 @@ #include "RNA_access.h" +#include "ED_buttons.h" #include "ED_armature.h" #include "ED_screen.h" #include "ED_physics.h" @@ -1179,3 +1180,28 @@ ID *buttons_context_id_path(const bContext *C) return NULL; } + +void ED_buttons_id_unref(SpaceButs *sbuts, const ID *id) +{ + if (sbuts->path) { + ButsContextPath *path = sbuts->path; + int i; + + for (i = 0; i < path->len; i++) { + if (path->ptr[i].id.data == id) { + break; + } + } + + if (i == path->len) { + /* pass */ + } + else if (i == 0) { + MEM_SAFE_FREE(sbuts->path); + } + else { + memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i)); + path->len = i; + } + } +} diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 438eb1f3864..d162becfe98 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -38,6 +38,7 @@ #include "DNA_mesh_types.h" #include "DNA_object_types.h" #include "DNA_screen_types.h" +#include "DNA_space_types.h" #include "DNA_scene_types.h" #include "DNA_packedFile_types.h" @@ -58,9 +59,11 @@ #include "BKE_paint.h" #include "ED_armature.h" +#include "ED_buttons.h" #include "ED_image.h" #include "ED_mesh.h" #include "ED_object.h" +#include "ED_outliner.h" #include "ED_paint.h" #include "ED_space_api.h" #include "ED_util.h" @@ -318,3 +321,21 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info glEnd(); setlinestyle(0); } + +/** + * Use to free ID references within runtime data (stored outside of DNA) + * + * \note Typically notifiers take care of this, + * but there are times we have to free references immediately, see: T44376 + */ +void ED_spacedata_id_unref(struct SpaceLink *sl, const ID *id) +{ + switch (sl->spacetype) { + case SPACE_OUTLINER: + ED_outliner_id_unref((SpaceOops *)sl, id); + break; + case SPACE_BUTS: + ED_buttons_id_unref((SpaceButs *)sl, id); + break; + } +} diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 7ca82c0c03a..b5c267e8a39 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -153,6 +153,7 @@ void WM_init(bContext *C, int argc, const char **argv) BKE_library_callback_free_notifier_reference_set(WM_main_remove_notifier_reference); /* library.c */ BKE_library_callback_free_editor_id_reference_set(WM_main_remove_editor_id_reference); /* library.c */ BKE_blender_callback_test_break_set(wm_window_testbreak); /* blender.c */ + BKE_spacedata_callback_id_unref_set(ED_spacedata_id_unref); /* screen.c */ DAG_editors_update_cb(ED_render_id_flush_update, ED_render_scene_update); /* depsgraph.c */ ED_spacetypes_init(); /* editors/space_api/spacetype.c */ |