url-mode: connect osc-8 links only when both ID and URI matches

Before this, two OSC-8 links with a matching ID would be connected
even if their URIs weren’t the same. This is against the spec:

  The same id is only used for connecting character cells whose URIs
  is also the same. Character cells pointing to different URIs should
  never be underlined together when hovering over.

https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#hover-underlining-and-the-id-parameter
This commit is contained in:
Daniel Eklöf 2022-08-30 17:48:04 +02:00
parent 4dd63bcc91
commit c753cf8f45
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 12 additions and 6 deletions

View file

@ -67,6 +67,8 @@
selected when they should not.
* Crash when either resizing the terminal window, or scrolling in the
scrollback history ([#1074][1074])
* OSC-8 URLs with matching IDs, but mismatching URIs being incorrectly
connected.
[1074]: https://codeberg.org/dnkl/foot/pulls/1074

View file

@ -677,18 +677,23 @@ urls_assign_key_combos(const struct config *conf, url_list_t *urls)
if (count == 0)
return;
uint64_t seen_ids[count];
char32_t *combos[count];
generate_key_combos(conf, count, combos);
size_t combo_idx = 0;
size_t id_idx = 0;
tll_foreach(*urls, it) {
bool id_already_seen = false;
for (size_t i = 0; i < id_idx; i++) {
if (it->item.id == seen_ids[i]) {
/* Look for already processed URLs where both the URI and the
* ID matches */
tll_foreach(*urls, it2) {
if (&it->item == &it2->item)
break;
if (it->item.id == it2->item.id &&
strcmp(it->item.url, it2->item.url) == 0)
{
id_already_seen = true;
break;
}
@ -696,7 +701,6 @@ urls_assign_key_combos(const struct config *conf, url_list_t *urls)
if (id_already_seen)
continue;
seen_ids[id_idx++] = it->item.id;
/*
* Scan previous URLs, and check if *this* URL matches any of
@ -730,7 +734,7 @@ urls_assign_key_combos(const struct config *conf, url_list_t *urls)
char *key = ac32tombs(it->item.key);
xassert(key != NULL);
LOG_DBG("URL: %s (%s)", it->item.url, key);
LOG_DBG("URL: %s (key=%s, id=%"PRIu64")", it->item.url, key, it->item.id);
free(key);
}
#endif