summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2026-02-08 03:54:06 +0100
committerGravatar Nikias Bassen2026-02-08 03:54:06 +0100
commit714ef4f95652bc5dde2bc1a461cac8c3a89a61c9 (patch)
tree16c666a3934c51723fd8aeb6d1502eae28b601ae
parent1df039994ff2368bc64ea4bc38d9261e6153437c (diff)
downloadlibplist-714ef4f95652bc5dde2bc1a461cac8c3a89a61c9.tar.gz
libplist-714ef4f95652bc5dde2bc1a461cac8c3a89a61c9.tar.bz2
libcnary: Fix node_detach to fully clear parent relationship
Ensure node_detach() clears child->parent after removal and handles missing children lists safely. This makes detached nodes reusable and allows correct rollback when reinserting nodes after failed inserts (e.g. depth-limit failures). Without this, detached nodes could remain logically parented, causing inconsistent state and preventing reinsertion.
-rw-r--r--libcnary/node.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/libcnary/node.c b/libcnary/node.c
index 9457548..c152f91 100644
--- a/libcnary/node.c
+++ b/libcnary/node.c
@@ -162,9 +162,15 @@ int node_attach(node_t parent, node_t child)
int node_detach(node_t parent, node_t child)
{
if (!parent || !child) return NODE_ERR_INVALID_ARG;
+ if (!parent->children) return NODE_ERR_NOT_FOUND;
+ if (child->parent && child->parent != parent) return NODE_ERR_PARENT;
+
int node_index = node_list_remove(parent->children, child);
if (node_index >= 0) {
- parent->count--;
+ if (parent->count > 0) parent->count--;
+ child->parent = NULL;
+ child->prev = NULL;
+ child->next = NULL;
}
return node_index;
}