From 9aa8301367ee499b102fbd096a9fa8d927521d55 Mon Sep 17 00:00:00 2001 From: aPiecek Date: Thu, 17 Oct 2024 15:40:17 +0200 Subject: [PATCH] lyds_tree BUGFIX for-iteration over lyd and unlink Watch out for infinite loops when iterating over nodes while reordering. --- src/tree_data.c | 4 ++-- src/tree_data_sorted.c | 12 +++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/tree_data.c b/src/tree_data.c index a8c42bf19..84884013f 100644 --- a/src/tree_data.c +++ b/src/tree_data.c @@ -548,7 +548,7 @@ lyd_insert_after_node(struct lyd_node **first_sibling_p, struct lyd_node *siblin struct lyd_node_inner *par; struct lyd_node *first_sibling; - assert(!node->next && (node->prev == node)); + assert(!node->next && (node->prev == node) && (sibling != node)); if (sibling->next) { /* sibling had a succeeding node */ @@ -584,7 +584,7 @@ lyd_insert_before_node(struct lyd_node *sibling, struct lyd_node *node) { struct lyd_node_inner *par; - assert(!node->next && (node->prev == node)); + assert(!node->next && (node->prev == node) && (sibling != node)); node->next = sibling; /* covers situation of sibling being first */ diff --git a/src/tree_data_sorted.c b/src/tree_data_sorted.c index 69a459bb3..ce0820ce7 100644 --- a/src/tree_data_sorted.c +++ b/src/tree_data_sorted.c @@ -935,7 +935,7 @@ lyds_pool_clean(struct lyds_pool *pool) pool->rbn = NULL; for (meta = pool->meta; meta; meta = next) { - next = meta->next ? meta->next : NULL; + next = meta->next; RBT_SET(meta, NULL); lyd_free_meta_single(meta); } @@ -1055,9 +1055,10 @@ lyds_additionally_create_rb_nodes(struct lyd_node **first_sibling, struct lyd_no LY_ERR ret; ly_bool max; struct rb_node *rbn; - struct lyd_node *iter; + struct lyd_node *iter, *next; - for (iter = node; iter && (iter->schema == (*leader)->schema); iter = iter->next) { + for (iter = node; iter && (iter->schema == (*leader)->schema); iter = next) { + next = iter->next; ret = lyds_create_node(iter, &rbn); LY_CHECK_RET(ret); rb_insert_node(rbt, rbn, &max); @@ -1118,7 +1119,7 @@ lyds_additionally_reuse_rb_tree(struct lyd_node **first_sibling, struct lyd_node struct rb_node **rbt, struct lyds_pool *pool, struct lyd_node **next) { ly_bool max; - struct lyd_node *iter; + struct lyd_node *iter, *next_node; /* let's begin with the leader */ RBN_RESET(pool->rbn, *leader); @@ -1126,7 +1127,8 @@ lyds_additionally_reuse_rb_tree(struct lyd_node **first_sibling, struct lyd_node pool->rbn = rb_iter_next(&pool->iter_state); /* continue with the rest of the nodes */ - for (iter = (*leader)->next; iter && (iter->schema == (*leader)->schema); iter = iter->next) { + for (iter = (*leader)->next; iter && (iter->schema == (*leader)->schema); iter = next_node) { + next_node = iter->next; if (!pool->rbn) { *next = iter; return;