slist: Fix sys_slist_append_list with head and tail NULL break a list

If the sys_slist_t instance is not empty, its head and tail points to
some sys_snode_t instances. If sys_slist_append_list is executed with
tail being NULL the list object is corrupted. Tail of the sys_slist_t
instance is set to NULL. If one executes sys_slist_append on that node,
then nodes pointed by head are lost.

The commit fixes the issue and adds unit tests to verify correct
behavior.

Added change verifies if head and tail of appended list are not NULL.
In other case the list object is invalid and should not be appended
to a valid list instance.

Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
Piotr Pryga 2022-04-03 02:04:21 +02:00 committed by Marti Bolivar
parent 7b43deedd5
commit 4a18d615a4
2 changed files with 36 additions and 9 deletions

View file

@ -115,16 +115,18 @@
sys_ ## __lname ## _append_list(sys_ ## __lname ## _t *list, \
void *head, void *tail) \
{ \
if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
z_ ## __lname ## _head_set(list, \
(sys_ ## __nname ## _t *)head); \
} else { \
z_ ## __nname ## _next_set( \
sys_ ## __lname ## _peek_tail(list), \
(sys_ ## __nname ## _t *)head); \
if (head != NULL && tail != NULL) { \
if (sys_ ## __lname ## _peek_tail(list) == NULL) { \
z_ ## __lname ## _head_set(list, \
(sys_ ## __nname ## _t *)head); \
} else { \
z_ ## __nname ## _next_set( \
sys_ ## __lname ## _peek_tail(list), \
(sys_ ## __nname ## _t *)head); \
} \
z_ ## __lname ## _tail_set(list, \
(sys_ ## __nname ## _t *)tail); \
} \
z_ ## __lname ## _tail_set(list, \
(sys_ ## __nname ## _t *)tail); \
}
#define Z_GENLIST_MERGE_LIST(__lname, __nname) \

View file

@ -368,6 +368,18 @@ void test_slist(void)
((struct data_node *)node)->data);
}
/* test sys_slist_append_list with emtpy list */
sys_slist_init(&test_list);
sys_slist_init(&append_list);
for (ii = 0; ii < 6; ii++) {
/* regenerate test_list only */
sys_slist_append(&test_list, &data_node[ii].node);
}
sys_slist_append_list(&test_list, append_list.head, append_list.tail);
node = sys_slist_peek_tail(&test_list);
zassert_equal(((struct data_node *)node)->data, data_node[5].data, "expected %d got %d",
data_node[5].data, ((struct data_node *)node)->data);
/* test sys_slist_merge_slist */
sys_slist_init(&test_list);
sys_slist_init(&append_list);
@ -385,6 +397,19 @@ void test_slist(void)
}
zassert_true(sys_slist_is_empty(&append_list),
"merged list is not empty");
/* test sys_slist_merge_slist with emtpy list */
sys_slist_init(&test_list);
sys_slist_init(&append_list);
for (ii = 0; ii < 6; ii++) {
/* regenerate test_list only */
sys_slist_append(&test_list, &data_node[ii].node);
}
sys_slist_merge_slist(&test_list, &append_list);
node = sys_slist_peek_tail(&test_list);
zassert_equal(((struct data_node *)node)->data, data_node[5].data, "expected %d got %d",
data_node[5].data, ((struct data_node *)node)->data);
}
/**