diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-10-27 15:56:21 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-10-27 15:56:21 +0400 |
commit | 9c2eaad7aac8b674bcb927c32a296ed8e10b90d0 (patch) | |
tree | 7d86a9a8f08760b2667ef7b7175bca4bb24142cc /source/blender/blenloader/intern/readfile.c | |
parent | 9fc95bd7ee2aed9d4de7c3c05dfef6597b83a332 (diff) |
Fix #32982, Segault when trying to show a node material.
This was caused by incomplete pointer mapping of the node->internal_links list in r51630, my bad. In intermediate revisions this could lead to corrupted .blend data. This patch adds a do_versions check to remove such bad links. The correct internal_links list will get restored on node update.
Diffstat (limited to 'source/blender/blenloader/intern/readfile.c')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 070c6b2d58b..de9e5f5e08e 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2414,6 +2414,12 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree) link_list(fd, &node->outputs); link_list(fd, &node->internal_links); + for (link = node->internal_links.first; link; link = link->next) { + link->fromnode = newdataadr(fd, link->fromnode); + link->fromsock = newdataadr(fd, link->fromsock); + link->tonode = newdataadr(fd, link->tonode); + link->tosock = newdataadr(fd, link->tosock); + } if (node->type == CMP_NODE_MOVIEDISTORTION) { node->storage = newmclipadr(fd, node->storage); @@ -7117,6 +7123,21 @@ static void do_version_node_cleanup_dynamic_sockets_264(void *UNUSED(data), ID * } } +static void do_version_node_fix_internal_links_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + bNodeLink *link, *nextlink; + + for (node = ntree->nodes.first; node; node = node->next) { + for (link = node->internal_links.first; link; link = nextlink) { + nextlink = link->next; + if (!link->fromnode || !link->fromsock || !link->tonode || !link->tosock) { + BLI_remlink(&node->internal_links, link); + } + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -8204,6 +8225,28 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } } + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 6)) { + /* Fix for bug #32982, internal_links list could get corrupted from r51630 onward. + * Simply remove bad internal_links lists to avoid NULL pointers. + */ + bNodeTreeType *ntreetype; + bNodeTree *ntree; + + ntreetype = ntreeGetType(NTREE_COMPOSIT); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_internal_links_264); + ntreetype = ntreeGetType(NTREE_SHADER); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_internal_links_264); + ntreetype = ntreeGetType(NTREE_TEXTURE); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_fix_internal_links_264); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_version_node_fix_internal_links_264(NULL, NULL, ntree); + + } + /* WATCH IT!!!: pointers from libdata have not been converted yet here! */ /* WATCH IT 2!: Userdef struct init has to be in editors/interface/resources.c! */ |