mirror of
https://github.com/git/git.git
synced 2025-01-26 17:33:34 +08:00
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>
This commit is contained in:
parent
522cc87fdc
commit
17d23e8a38
@ -899,6 +899,12 @@ test_expect_success SIZE_T_IS_64BIT 'log --pretty with overflowing wrapping dire
|
||||
test_cmp expect error
|
||||
'
|
||||
|
||||
test_expect_success 'log --pretty with padding and preceding control chars' '
|
||||
printf "\20\20 0" >expect &&
|
||||
git log -1 --pretty="format:%x10%x10%>|(4)%x30" >actual &&
|
||||
test_cmp expect actual
|
||||
'
|
||||
|
||||
test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message' '
|
||||
# We only assert that this command does not crash. This needs to be
|
||||
# executed with the address sanitizer to demonstrate failure.
|
||||
|
8
utf8.c
8
utf8.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user