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:
parent
7b43deedd5
commit
4a18d615a4
|
@ -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) \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue