string-util: don't miss ANSI sequence at the very end in previous_ansi_sequence()
The backwards scan started at offset length-3, so the last position at which a
sequence can begin, length-2, was never examined. CSI sequences are at least
three bytes long and were thus unaffected, but two byte Fe sequences (ESC
followed by 0x40…0x5F) terminating the examined slice were missed.
ellipsize_mem() calls this to figure out whether a sequence ends exactly at the
current position, so that it can be skipped over, which is precisely the case
that was broken: such a sequence was instead counted as two visible cells and
copied through as text, and the string was ellipsized more aggressively than
requested. For example ellipsize("🐱🐱\x1bM🐱🐱\x1bM", 5, 0) returned a three
cell wide string rather than the five cells asked for.
This commit is contained in:
committed by
Yu Watanabe
parent
3e04f8f450
commit
2bb179632f
@@ -293,13 +293,15 @@ static size_t previous_ansi_sequence(const char *s, size_t length, const char **
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = length - 2; i > 0; i--) { /* -2 because at least two bytes are needed */
|
||||
size_t slen = ansi_sequence_length(s + (i - 1), length - (i - 1));
|
||||
if (slen == 0)
|
||||
continue;
|
||||
for (size_t i = length - 2;; i--) { /* -2 because at least two bytes are needed */
|
||||
size_t slen = ansi_sequence_length(s + i, length - i);
|
||||
if (slen > 0) {
|
||||
*ret_where = s + i;
|
||||
return slen;
|
||||
}
|
||||
|
||||
*ret_where = s + (i - 1);
|
||||
return slen;
|
||||
if (i == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
*ret_where = NULL;
|
||||
|
||||
Reference in New Issue
Block a user