mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-02-04 04:06:06 -05:00
vt: prevent potential endless loop when finding a slot for a composed character
Composed characters are stored in a tree structure, using a key as identifier. The key is calculated from the individual characters that make up the composed character sequence. Since the address space for keys is limited, collisions may occur. In this case, we simply increment the key and try again. It is theoretically possible to saturate the key space, in which case we’ll get stuck in an endless loop. Even if the key space isn’t fully saturated, we fairly easy reach a point where there are so many collisions for each insertion, that performance drops significantly. Since key space is limited (it’s not like a hash table that we can grow), our only option is to limit the number of collisions. If we can’t find a slot within a hard code amount of collisions, the character is simply dropped.
This commit is contained in:
parent
dbe2c0a068
commit
edd68732ad
1 changed files with 14 additions and 0 deletions
14
vt.c
14
vt.c
|
|
@ -738,8 +738,20 @@ action_utf8_print(struct terminal *term, char32_t wc)
|
|||
|
||||
xassert(wanted_count <= 255);
|
||||
|
||||
size_t collision_count = 0;
|
||||
|
||||
/* Look for existing combining chain */
|
||||
while (true) {
|
||||
if (collision_count > 128) {
|
||||
static bool have_warned = false;
|
||||
if (!have_warned) {
|
||||
have_warned = true;
|
||||
LOG_WARN("ignoring composed character: "
|
||||
"too many collisions in hash table");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const struct composed *cc = composed_lookup(term->composed, key);
|
||||
if (cc == NULL)
|
||||
break;
|
||||
|
|
@ -756,6 +768,7 @@ action_utf8_print(struct terminal *term, char32_t wc)
|
|||
cc->chars[wanted_count - 1] != wc)
|
||||
{
|
||||
key++;
|
||||
collision_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -766,6 +779,7 @@ action_utf8_print(struct terminal *term, char32_t wc)
|
|||
|
||||
if (!match) {
|
||||
key++;
|
||||
collision_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue