Fix T102386: crash when trying to link sockets from different node trees

This was caused by rBc39eb09ae587e1d9. The optimization broke the case
when the socket is not in the provided node tree. Now there are two separate
functions, one that always does the slow check to see of the socket is really
in the node tree and a potentially much faster version when we are sure
that the socket is in the tree.
This commit is contained in:
Jacques Lucke 2022-11-11 11:48:56 +01:00
parent 84c66fe9db
commit 57dd1b7799
Notes: blender-bot 2023-02-14 08:25:14 +01:00
Referenced by issue #102386, Crash with EXCEPTION_ACCESS_VIOLATION When Shift+Alt+Clicking in Geonodes
4 changed files with 20 additions and 9 deletions

View File

@ -746,7 +746,14 @@ struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name);
/**
* Finds a node based on given socket and returns true on success.
*/
bool nodeFindNode(struct bNodeTree *ntree,
bool nodeFindNodeTry(struct bNodeTree *ntree,
struct bNodeSocket *sock,
struct bNode **r_node,
int *r_sockindex);
/**
* Same as above but expects that the socket definitely is in the node tree.
*/
void nodeFindNode(struct bNodeTree *ntree,
struct bNodeSocket *sock,
struct bNode **r_node,
int *r_sockindex);

View File

@ -2019,7 +2019,7 @@ bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name)
return (bNode *)BLI_findstring(&ntree->nodes, name, offsetof(bNode, name));
}
bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
void nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
{
*r_node = nullptr;
if (!ntree->runtime->topology_cache_is_dirty) {
@ -2029,9 +2029,15 @@ bool nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_so
ListBase *sockets = (sock->in_out == SOCK_IN) ? &node->inputs : &node->outputs;
*r_sockindex = BLI_findindex(sockets, sock);
}
return true;
return;
}
const bool success = nodeFindNodeTry(ntree, sock, r_node, r_sockindex);
BLI_assert(success);
UNUSED_VARS_NDEBUG(success);
}
bool nodeFindNodeTry(bNodeTree *ntree, bNodeSocket *sock, bNode **r_node, int *r_sockindex)
{
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
ListBase *sockets = (sock->in_out == SOCK_IN) ? &node->inputs : &node->outputs;
int i;

View File

@ -1165,7 +1165,7 @@ bool UI_context_copy_to_selected_list(bContext *C,
if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) {
bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data);
if (nodeFindNode(ntree, sock, &node, nullptr)) {
if (nodeFindNodeTry(ntree, sock, &node, nullptr)) {
if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != nullptr) {
/* we're good! */
}

View File

@ -1302,8 +1302,8 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree,
return NULL;
}
nodeFindNode(ntree, fromsock, &fromnode, NULL);
nodeFindNode(ntree, tosock, &tonode, NULL);
nodeFindNodeTry(ntree, fromsock, &fromnode, NULL);
nodeFindNodeTry(ntree, tosock, &tonode, NULL);
/* check validity of the sockets:
* if sockets from different trees are passed in this will fail!
*/
@ -2789,9 +2789,7 @@ static char *rna_NodeSocket_path(const PointerRNA *ptr)
int socketindex;
char name_esc[sizeof(node->name) * 2];
if (!nodeFindNode(ntree, sock, &node, &socketindex)) {
return NULL;
}
nodeFindNode(ntree, sock, &node, &socketindex);
BLI_str_escape(name_esc, node->name, sizeof(name_esc));