From 74dc4e87a6df2826f26eb94eaff8fe02a3911c24 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 4 May 2015 18:02:56 +1000 Subject: Fix Buttons context, invalid object data access Another instance of T44376. Crash where the Python context would access a stale pointer to the active object. --- source/blender/blenkernel/intern/object.c | 20 ++------- source/blender/blenkernel/intern/scene.c | 49 ++-------------------- source/blender/editors/include/ED_node.h | 2 + .../editors/space_buttons/buttons_context.c | 5 +++ source/blender/editors/space_node/node_edit.c | 28 +++++++++++++ source/blender/editors/util/ed_util.c | 5 +++ .../blender/windowmanager/intern/wm_event_system.c | 6 +-- 7 files changed, 47 insertions(+), 68 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 111aa84e688..bd0b7275174 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -808,25 +808,11 @@ void BKE_object_unlink(Object *ob) } } } - else if (sl->spacetype == SPACE_OUTLINER) { +#if 0 + else if (ELEM(sl->spacetype, SPACE_OUTLINER, SPACE_BUTS, SPACE_NODE)) { /* now handled by WM_main_remove_editor_id_reference */ } - else if (sl->spacetype == SPACE_BUTS) { - SpaceButs *sbuts = (SpaceButs *)sl; - - if (sbuts->pinid == (ID *)ob) { - sbuts->flag &= ~SB_PIN_CONTEXT; - sbuts->pinid = NULL; - } - } - else if (sl->spacetype == SPACE_NODE) { - SpaceNode *snode = (SpaceNode *)sl; - - if (snode->from == (ID *)ob) { - snode->flag &= ~SNODE_PIN; - snode->from = NULL; - } - } +#endif } sa = sa->next; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 495b3516c0d..052308bfac8 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -799,36 +799,6 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name) return NULL; } -static void scene_unlink_space_node(SpaceNode *snode, Scene *sce) -{ - if (snode->id == &sce->id) { - /* nasty DNA logic for SpaceNode: - * ideally should be handled by editor code, but would be bad level call - */ - bNodeTreePath *path, *path_next; - for (path = snode->treepath.first; path; path = path_next) { - path_next = path->next; - MEM_freeN(path); - } - BLI_listbase_clear(&snode->treepath); - - snode->id = NULL; - snode->from = NULL; - snode->nodetree = NULL; - snode->edittree = NULL; - } -} - -static void scene_unlink_space_buts(SpaceButs *sbuts, Scene *sce) -{ - if (sbuts->pinid == &sce->id) { - sbuts->pinid = NULL; - sbuts->flag &= ~SB_PIN_CONTEXT; - } - - BKE_spacedata_id_unref((SpaceLink *)sbuts, &sce->id); -} - void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce) { Scene *sce1; @@ -853,24 +823,11 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce) /* all screens */ for (screen = bmain->screen.first; screen; screen = screen->id.next) { - ScrArea *area; - - if (screen->scene == sce) + if (screen->scene == sce) { screen->scene = newsce; - - for (area = screen->areabase.first; area; area = area->next) { - SpaceLink *space_link; - for (space_link = area->spacedata.first; space_link; space_link = space_link->next) { - switch (space_link->spacetype) { - case SPACE_NODE: - scene_unlink_space_node((SpaceNode *)space_link, sce); - break; - case SPACE_BUTS: - scene_unlink_space_buts((SpaceButs *)space_link, sce); - break; - } - } } + + /* editors are handled by WM_main_remove_editor_id_reference */ } BKE_libblock_free(bmain, sce); diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h index b02ebeb650b..1445308c485 100644 --- a/source/blender/editors/include/ED_node.h +++ b/source/blender/editors/include/ED_node.h @@ -103,6 +103,8 @@ void ED_node_set_active(struct Main *bmain, struct bNodeTree *ntree, struct bNod void ED_node_composite_job(const struct bContext *C, struct bNodeTree *nodetree, struct Scene *scene_owner); +void ED_node_id_unref(struct SpaceNode *snode, const ID *id); + /* node_ops.c */ void ED_operatormacros_node(void); diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index b00a2c54ff9..bc42f1dd5bb 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -1183,6 +1183,11 @@ ID *buttons_context_id_path(const bContext *C) void ED_buttons_id_unref(SpaceButs *sbuts, const ID *id) { + if (sbuts->pinid == id) { + sbuts->pinid = NULL; + sbuts->flag &= ~SB_PIN_CONTEXT; + } + if (sbuts->path) { ButsContextPath *path = sbuts->path; int i; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 360087d77c7..ffd51bcc44e 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -740,6 +740,34 @@ void ED_node_set_active(Main *bmain, bNodeTree *ntree, bNode *node) } } +void ED_node_id_unref(SpaceNode *snode, const ID *id) +{ + if (GS(id->name) == ID_SCE) { + if (snode->id == id) { + /* nasty DNA logic for SpaceNode: + * ideally should be handled by editor code, but would be bad level call + */ + bNodeTreePath *path, *path_next; + for (path = snode->treepath.first; path; path = path_next) { + path_next = path->next; + MEM_freeN(path); + } + BLI_listbase_clear(&snode->treepath); + + snode->id = NULL; + snode->from = NULL; + snode->nodetree = NULL; + snode->edittree = NULL; + } + } + else if (GS(id->name) == ID_OB) { + if (snode->from == id) { + snode->flag &= ~SNODE_PIN; + snode->from = NULL; + } + } +} + void ED_node_post_apply_transform(bContext *UNUSED(C), bNodeTree *UNUSED(ntree)) { /* XXX This does not work due to layout functions relying on node->block, diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index d162becfe98..433c7603f35 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -62,6 +62,7 @@ #include "ED_buttons.h" #include "ED_image.h" #include "ED_mesh.h" +#include "ED_node.h" #include "ED_object.h" #include "ED_outliner.h" #include "ED_paint.h" @@ -330,6 +331,7 @@ void ED_region_draw_mouse_line_cb(const bContext *C, ARegion *ar, void *arg_info */ void ED_spacedata_id_unref(struct SpaceLink *sl, const ID *id) { + switch (sl->spacetype) { case SPACE_OUTLINER: ED_outliner_id_unref((SpaceOops *)sl, id); @@ -337,5 +339,8 @@ void ED_spacedata_id_unref(struct SpaceLink *sl, const ID *id) case SPACE_BUTS: ED_buttons_id_unref((SpaceButs *)sl, id); break; + case SPACE_NODE: + ED_node_id_unref((SpaceNode *)sl, id); + break; } } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index f054c5a43c1..69bee8bab80 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -246,11 +246,7 @@ void WM_main_remove_editor_id_reference(const ID *id) 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); - } + ED_spacedata_id_unref(sl, id); } } } -- cgit v1.2.3