diff options
| author | 2026-02-08 03:54:06 +0100 | |
|---|---|---|
| committer | 2026-02-08 03:54:06 +0100 | |
| commit | 714ef4f95652bc5dde2bc1a461cac8c3a89a61c9 (patch) | |
| tree | 16c666a3934c51723fd8aeb6d1502eae28b601ae | |
| parent | 1df039994ff2368bc64ea4bc38d9261e6153437c (diff) | |
| download | libplist-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.c | 8 |
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) | |||
| 162 | int node_detach(node_t parent, node_t child) | 162 | int node_detach(node_t parent, node_t child) |
| 163 | { | 163 | { |
| 164 | if (!parent || !child) return NODE_ERR_INVALID_ARG; | 164 | if (!parent || !child) return NODE_ERR_INVALID_ARG; |
| 165 | if (!parent->children) return NODE_ERR_NOT_FOUND; | ||
| 166 | if (child->parent && child->parent != parent) return NODE_ERR_PARENT; | ||
| 167 | |||
| 165 | int node_index = node_list_remove(parent->children, child); | 168 | int node_index = node_list_remove(parent->children, child); |
| 166 | if (node_index >= 0) { | 169 | if (node_index >= 0) { |
| 167 | parent->count--; | 170 | if (parent->count > 0) parent->count--; |
| 171 | child->parent = NULL; | ||
| 172 | child->prev = NULL; | ||
| 173 | child->next = NULL; | ||
| 168 | } | 174 | } |
| 169 | return node_index; | 175 | return node_index; |
| 170 | } | 176 | } |
