[Bf-blender-cvs] [193dd13] master: Fix T37698: Crash from invalid context access when freeing custom python nodes on Blender exit.

Lukas Tönne noreply at git.blender.org
Thu Dec 5 15:13:51 CET 2013


Commit: 193dd134da443245920a8d4cff4e46a97a04a761
Author: Lukas Tönne
Date:   Thu Dec 5 15:02:17 2013 +0100
http://developer.blender.org/rB193dd134da443245920a8d4cff4e46a97a04a761

Fix T37698: Crash from invalid context access when freeing custom
python nodes on Blender exit.

The nodeFreeNode function is calling a customizable freefunc callback,
which can be implemented by python. However, the context is invalid when
using this callback while the node tree data block is freed on exit.
Luckily it is also not necessary: When freeing the bNodeTree data blocks
all that is needed is freeing of the DNA data, no other side effects
should happen. So now disable the api callbacks when freeing nodes in
the ntreeFreeTree function.

Also some minor cleanup: checking node->typeinfo is not necessary, all
nodes will always have a valid typeinfo pointer - if a node type is
unknown this will be a stub bNodeType to avoid the need for such checks.

===================================================================

M	source/blender/blenkernel/intern/node.c

===================================================================

diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index c3d08b6..6f29221 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1588,14 +1588,14 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
 }
 
 /** \note caller needs to manage node->id user */
-void nodeFreeNode(bNodeTree *ntree, bNode *node)
+static void node_free_node_ex(bNodeTree *ntree, bNode *node, bool use_api_free_cb)
 {
 	bNodeSocket *sock, *nextsock;
 	char propname_esc[MAX_IDPROP_NAME * 2];
 	char prefix[MAX_IDPROP_NAME * 2];
 	
 	/* extra free callback */
-	if (node->typeinfo && node->typeinfo->freefunc_api) {
+	if (use_api_free_cb && node->typeinfo->freefunc_api) {
 		PointerRNA ptr;
 		RNA_pointer_create((ID *)ntree, &RNA_Node, node, &ptr);
 		
@@ -1617,7 +1617,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
 
 		BKE_animdata_fix_paths_remove((ID *)ntree, prefix);
 
-		if (ntree->typeinfo && ntree->typeinfo->free_node_cache)
+		if (ntree->typeinfo->free_node_cache)
 			ntree->typeinfo->free_node_cache(ntree, node);
 		
 		/* texture node has bad habit of keeping exec data around */
@@ -1626,7 +1626,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
 			ntree->execdata = NULL;
 		}
 		
-		if (node->typeinfo && node->typeinfo->freefunc)
+		if (node->typeinfo->freefunc)
 			node->typeinfo->freefunc(node);
 	}
 	
@@ -1654,6 +1654,11 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
 		ntree->update |= NTREE_UPDATE_NODES;
 }
 
+void nodeFreeNode(bNodeTree *ntree, bNode *node)
+{
+	node_free_node_ex(ntree, node, true);
+}
+
 static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *sock)
 {
 	if (sock->prop) {
@@ -1736,7 +1741,7 @@ void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
 		(void)do_id_user;
 #endif
 
-		nodeFreeNode(ntree, node);
+		node_free_node_ex(ntree, node, false);
 	}
 
 	/* free interface sockets */
@@ -2507,7 +2512,7 @@ void BKE_node_clipboard_clear(void)
 	
 	for (node = node_clipboard.nodes.first; node; node = node_next) {
 		node_next = node->next;
-		nodeFreeNode(NULL, node);
+		node_free_node_ex(NULL, node, false);
 	}
 	node_clipboard.nodes.first = node_clipboard.nodes.last = NULL;




More information about the Bf-blender-cvs mailing list