aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Primak <vyivel@eclair.cafe>2023-10-08 13:21:00 +0300
committerSimon Ser <contact@emersion.fr>2023-10-08 11:06:09 +0000
commit2c33a1c2de1a675d84ede6b0d751cb28abeb7e44 (patch)
tree000f5af5243f3343b58ca5b6291d132de9bd904c
parentb06c2f3d1fef3b4d75bd846c832234bf722c0d7e (diff)
util/addon: make wlr_addon_set_finish() safer
wl_list_for_each_safe() breaks if an item immediately after the current one is removed, see https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4358#note_2106260.
-rw-r--r--util/addon.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/util/addon.c b/util/addon.c
index 0f9037a2..63bcb5b6 100644
--- a/util/addon.c
+++ b/util/addon.c
@@ -11,16 +11,16 @@ void wlr_addon_set_init(struct wlr_addon_set *set) {
}
void wlr_addon_set_finish(struct wlr_addon_set *set) {
- struct wlr_addon *addon, *tmp;
- wl_list_for_each_safe(addon, tmp, &set->addons, link) {
+ while (!wl_list_empty(&set->addons)) {
+ struct wl_list *link = set->addons.next;
+ struct wlr_addon *addon = wl_container_of(link, addon, link);
+ const struct wlr_addon_interface *impl = addon->impl;
addon->impl->destroy(addon);
+ if (set->addons.next == link) {
+ wlr_log(WLR_ERROR, "Dangling addon: %s", impl->name);
+ abort();
+ }
}
-
- wl_list_for_each(addon, &set->addons, link) {
- wlr_log(WLR_ERROR, "Dangling addon: %s", addon->impl->name);
- }
-
- assert(wl_list_empty(&set->addons));
}
void wlr_addon_init(struct wlr_addon *addon, struct wlr_addon_set *set,