url-mode: fix crash when removing duplicate and/or overlapping URLs

Removing overlaping and duplicated URLs is done by running two nested
loops, that both iterate the same URL list.

When a duplicate is found, one of the URLs is destroyed and removed
from the list.

Deleting and removing an item *is* safe, but only as long as _no
other_ iterator has references to it.

In this case, if we remove an item from e.g. the inner iterator, we’ll
crash if the outer iterator’s *next* item is the item being removed.

Closes #627
This commit is contained in:
Daniel Eklöf 2021-07-11 10:06:12 +02:00
parent a9872aac5a
commit cf6d04f9f2
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 14 additions and 7 deletions

View file

@ -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