From: Arran Cudbard-Bell Date: Mon, 6 Sep 2021 20:31:59 +0000 (-0500) Subject: Fix fr_dlist_foreach_safe X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eca327a0f2bb3784418985ffeab6cf2bf5e7e0de;p=thirdparty%2Ffreeradius-server.git Fix fr_dlist_foreach_safe --- diff --git a/src/lib/util/dlist.h b/src/lib/util/dlist.h index d995ada6e91..71197bf9d90 100644 --- a/src/lib/util/dlist.h +++ b/src/lib/util/dlist.h @@ -87,8 +87,8 @@ static_assert(sizeof(unsigned int) >= 4, "Unsigned integer too small on this pla for (_iter = fr_dlist_head(_list_head), \ _tmp = fr_dlist_head(_list_head) ? *fr_dlist_item_to_entry((_list_head)->offset, fr_dlist_head(_list_head)) : (fr_dlist_t){ .prev = NULL, .next = NULL }; \ _iter; \ - _iter = _tmp.next ? fr_dlist_entry_to_item((_list_head)->offset, _tmp.next) : NULL, \ - _tmp = _tmp.next ? *_tmp.next : (fr_dlist_t){ .prev = NULL, .next = NULL }) + _iter = _tmp.next && (_tmp.next != &(_list_head)->entry) ? fr_dlist_entry_to_item((_list_head)->offset, _tmp.next) : NULL, \ + _tmp = _tmp.next && (_tmp.next != &(_list_head)->entry) ? *_tmp.next : (fr_dlist_t){ .prev = NULL, .next = NULL }) /** Find the dlist pointers within a list item diff --git a/src/lib/util/dlist_tests.c b/src/lib/util/dlist_tests.c index edf0f535e90..2b48ae4a46f 100644 --- a/src/lib/util/dlist_tests.c +++ b/src/lib/util/dlist_tests.c @@ -162,13 +162,36 @@ static void test_dlist_entry_move(void) TEST_CHECK(a2.entry.prev == &a1.entry); } +static void test_dlist_foreach_safe(void) +{ + dlist_test_item_t a1 = { .id = "a1" }; + dlist_test_item_t a2 = { .id = "a2" }; + dlist_test_item_t a3 = { .id = "a3" }; + + fr_dlist_head_t head; + unsigned int count = 0; + + fr_dlist_init(&head, dlist_test_item_t, entry); + + fr_dlist_insert_tail(&head, &a1); + fr_dlist_insert_tail(&head, &a2); + fr_dlist_insert_tail(&head, &a3); + + fr_dlist_foreach_safe(&head, dlist_test_item_t, i) { + fr_dlist_remove(&head, i); + count++; + }} + + TEST_CHECK_RET((int)count, (int)3); +} + TEST_LIST = { /* * Allocation and management */ { "fr_dlist_move", test_dlist_move }, { "fr_dlist_entry_move", test_dlist_entry_move }, - + { "fr_dlist_foreach_safe", test_dlist_foreach_safe }, { NULL } };