diff --git a/CHANGELOG.md b/CHANGELOG.md index 44093dc5..acea5f9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,8 @@ last column, and `tweak.allow-overflowing-double-width-glyphs=yes`. * FD exhaustion when repeatedly entering/exiting URL mode with many URLs. +* Double free of URL while removing duplicated and/or overlapping URLs + in URL mode (https://codeberg.org/dnkl/foot/issues/627). ### Security diff --git a/terminal.h b/terminal.h index 94c1cf75..309f7db6 100644 --- a/terminal.h +++ b/terminal.h @@ -264,6 +264,7 @@ struct url { enum url_action action; bool url_mode_dont_change_url_attr; /* Entering/exiting URL mode doesn’t touch the cells’ attr.url */ bool osc8; + bool duplicate; }; typedef tll(struct url) url_list_t; diff --git a/url-mode.c b/url-mode.c index 8ac5631e..94c05b3a 100644 --- a/url-mode.c +++ b/url-mode.c @@ -470,16 +470,20 @@ remove_overlapping(url_list_t *urls, int cols) */ xassert(in->osc8 || out->osc8); - if (in->osc8) { - url_destroy(&outer->item); - tll_remove(*urls, outer); - } else { - url_destroy(&inner->item); - tll_remove(*urls, inner); - } + if (in->osc8) + outer->item.duplicate = true; + else + inner->item.duplicate = true; } } } + + tll_foreach(*urls, it) { + if (it->item.duplicate) { + url_destroy(&it->item); + tll_remove(*urls, it); + } + } } void