diff options
author | Patrick Steinhardt <ps@pks.im> | 2022-12-01 15:47:00 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-12-09 06:26:21 +0100 |
commit | 17d23e8a3812a5ca3dd6564e74d5250f22e5d76d (patch) | |
tree | ba8f2c2fe6a210bc7e839884f472c6ace93bf1d0 /utf8.c | |
parent | utf8: fix truncated string lengths in `utf8_strnwidth()` (diff) | |
download | git-17d23e8a3812a5ca3dd6564e74d5250f22e5d76d.tar.xz git-17d23e8a3812a5ca3dd6564e74d5250f22e5d76d.zip |
utf8: fix returning negative string width
The `utf8_strnwidth()` function calls `utf8_width()` in a loop and adds
its returned width to the end result. `utf8_width()` can return `-1`
though in case it reads a control character, which means that the
computed string width is going to be wrong. In the worst case where
there are more control characters than non-control characters, we may
even return a negative string width.
Fix this bug by treating control characters as having zero width.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'utf8.c')
-rw-r--r-- | utf8.c | 8 |
1 files changed, 6 insertions, 2 deletions
@@ -212,11 +212,15 @@ int utf8_strnwidth(const char *string, size_t len, int skip_ansi) const char *orig = string; while (string && string < orig + len) { - int skip; + int glyph_width, skip; + while (skip_ansi && (skip = display_mode_esc_sequence_len(string)) != 0) string += skip; - width += utf8_width(&string, NULL); + + glyph_width = utf8_width(&string, NULL); + if (glyph_width > 0) + width += glyph_width; } return string ? width : len; } |