diff options
author | Thomas Haller <thaller@redhat.com> | 2023-03-10 17:51:58 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-03-21 15:58:38 +0100 |
commit | 46703557fb98836532fe372b657dc02d0560e8df (patch) | |
tree | 32ed32321bc55223730b9490cc7847329529fb8d | |
parent | 037b0a2b2a904eb1c4922ef982586f70bbb4b423 (diff) |
glib-aux/prioq: ensure to clear "idx" when removing item from NMPrioq
NMPrioq is copied from systemd's "prioq.c". It uses the index pointer to
find elements in the heap directly. However, it's not very careful about
clearing or maintaining the index pointer if the element is not in the
queue. Like, find_item() accepts a bogus index and only finds the data
if the data and the index matches. That seems error prone.
In the first step, when we remove an item from the queue, ensure to
reset the index to NM_PRIOQ_IDX_NULL.
-rw-r--r-- | src/libnm-glib-aux/nm-prioq.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/src/libnm-glib-aux/nm-prioq.c b/src/libnm-glib-aux/nm-prioq.c index f548f60089..f5bc606854 100644 --- a/src/libnm-glib-aux/nm-prioq.c +++ b/src/libnm-glib-aux/nm-prioq.c @@ -100,6 +100,13 @@ nm_prioq_destroy(NMPrioq *q) _nm_assert_q(q); + while (q->_priv.n_items > 0) { + PrioqItem *i = &q->_priv.items[--q->_priv.n_items]; + + if (i->idx) + *i->idx = NM_PRIOQ_IDX_NULL; + } + free(q->_priv.items); q->_priv.compare_func = NULL; } @@ -238,11 +245,15 @@ remove_item(NMPrioq *q, PrioqItem *i) _nm_assert_item(q, i); - l = &q->_priv.items[q->_priv.n_items - 1u]; + if (i->idx) + *i->idx = NM_PRIOQ_IDX_NULL; + + q->_priv.n_items--; + + l = &q->_priv.items[q->_priv.n_items]; if (i == l) { - /* Last entry, let's just remove it */ - q->_priv.n_items--; + /* Last entry, nothing to do. */ return; } @@ -252,9 +263,9 @@ remove_item(NMPrioq *q, PrioqItem *i) k = i - q->_priv.items; *i = *l; + if (i->idx) *i->idx = k; - q->_priv.n_items--; k = shuffle_down(q, k); shuffle_up(q, k); |