From f243444490e8dcdaa399942b70e72d03005370f7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 19 Nov 2012 10:53:57 +1030 Subject: [PATCH] tal: tal_steal() fix. We call remove_node() in tal_steal, then re-use the node. So it's important that we always unlink the group property from the node for that case. Signed-off-by: Rusty Russell --- ccan/tal/tal.c | 3 ++- ccan/tal/test/run-steal.c | 40 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 ccan/tal/test/run-steal.c diff --git a/ccan/tal/tal.c b/ccan/tal/tal.c index ff25db19..474c0ff0 100644 --- a/ccan/tal/tal.c +++ b/ccan/tal/tal.c @@ -455,6 +455,7 @@ static struct tal_hdr *remove_node(struct tal_hdr *t) /* Are we the only one? */ if (prev == t) { + struct prop_hdr *next = (*prop)->next; struct children *c = group->parent_child; /* Is this the group embedded in the child property? */ if (group == &c->group) { @@ -462,9 +463,9 @@ static struct tal_hdr *remove_node(struct tal_hdr *t) } else { /* Empty group, so free it. */ list_del_from(&c->group.list, &group->list.n); - *prop = group->hdr.next; freefn(group); } + *prop = next; return c->parent; } else { /* Move property to next node. */ diff --git a/ccan/tal/test/run-steal.c b/ccan/tal/test/run-steal.c new file mode 100644 index 00000000..74a8235b --- /dev/null +++ b/ccan/tal/test/run-steal.c @@ -0,0 +1,40 @@ +#include +#include +#include + +int main(void) +{ + char *p[5]; + unsigned int i; + + plan_tests(9); + + p[0] = NULL; + for (i = 1; i < 5; i++) + p[i] = tal(p[i-1], char); + + tal_check(NULL, "check"); + /* Steal node with no children. */ + ok1(tal_steal(p[0], p[4]) == p[4]); + tal_check(NULL, "check"); + /* Noop steal. */ + ok1(tal_steal(p[0], p[4]) == p[4]); + tal_check(NULL, "check"); + /* Steal with children. */ + ok1(tal_steal(p[0], p[1]) == p[1]); + tal_check(NULL, "check"); + /* Noop steal. */ + ok1(tal_steal(p[0], p[1]) == p[1]); + tal_check(NULL, "check"); + /* Steal from direct child. */ + ok1(tal_steal(p[0], p[2]) == p[2]); + tal_check(NULL, "check"); + + ok1(tal_parent(p[1]) == p[0]); + ok1(tal_parent(p[2]) == p[0]); + ok1(tal_parent(p[3]) == p[2]); + ok1(tal_parent(p[4]) == p[0]); + tal_free(p[0]); + + return exit_status(); +} -- 2.39.2