From 11112d4d222d62d62ff8b7b2bcfae62c89d62162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 6 Feb 2014 10:10:59 +0100 Subject: Fix T38498: properly unlink scene pointers from SpaceNode. This fixes the first case mentioned in the report. Has to do some ugly DNA access to SpaceNode, unless we'd allow a bad level call there to do it in ED_node ... The second case has been fixed by @sergey in D274: https://developer.blender.org/D274?vs=838&id=879#toc So actually asan just did its job here, good to know! --- source/blender/blenkernel/intern/scene.c | 42 ++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 5 deletions(-) (limited to 'source/blender/blenkernel/intern/scene.c') diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 120a791d679..1088b3a2523 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -51,6 +51,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_sequence_types.h" +#include "DNA_space_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -717,10 +718,30 @@ 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); + } + snode->treepath.first = snode->treepath.last = NULL; + + snode->id = NULL; + snode->from = NULL; + snode->nodetree = NULL; + snode->edittree = NULL; + } +} + void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce) { Scene *sce1; - bScreen *sc; + bScreen *screen; /* check all sets */ for (sce1 = bmain->scene.first; sce1; sce1 = sce1->id.next) @@ -739,10 +760,21 @@ void BKE_scene_unlink(Main *bmain, Scene *sce, Scene *newsce) } } - /* al screens */ - for (sc = bmain->screen.first; sc; sc = sc->id.next) - if (sc->scene == sce) - sc->scene = newsce; + /* all screens */ + for (screen = bmain->screen.first; screen; screen = screen->id.next) { + ScrArea *area; + + 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) { + if (space_link->spacetype == SPACE_NODE) + scene_unlink_space_node((SpaceNode *)space_link, sce); + } + } + } BKE_libblock_free(bmain, sce); } -- cgit v1.2.3