Skip to content

Commit 59a255a

Browse files
committed
sideband: do not read beyond the end of input
The caller of maybe_colorize_sideband() gives a counted buffer <src, n>, but the callee checked src[] as if it were a NUL terminated buffer. If src[] had all isspace() bytes in it, we would have made n negative, and then (1) made number of strncasecmp() calls to see if the remaining bytes in src[] matched keywords, reading beyond the end of the array (this actually happens even if n does not go negative), and/or (2) called strbuf_add() with negative count, most likely triggering the "you want to use way too much memory" error due to unsigned integer overflow. Fix both issues by making sure we do not go beyond &src[n]. In the longer term we may want to accept size_t as parameter for clarity (even though we know that a sideband message we are painting typically would fit on a line on a terminal and int is sufficient). Write it down as a NEEDSWORK comment. Helped-by: Jonathan Nieder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bf1a11f commit 59a255a

File tree

2 files changed

+20
-2
lines changed

2 files changed

+20
-2
lines changed

sideband.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ void list_config_color_sideband_slots(struct string_list *list, const char *pref
6565
* Optionally highlight one keyword in remote output if it appears at the start
6666
* of the line. This should be called for a single line only, which is
6767
* passed as the first N characters of the SRC array.
68+
*
69+
* NEEDSWORK: use "size_t n" instead for clarity.
6870
*/
6971
static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
7072
{
@@ -75,7 +77,7 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
7577
return;
7678
}
7779

78-
while (isspace(*src)) {
80+
while (0 < n && isspace(*src)) {
7981
strbuf_addch(dest, *src);
8082
src++;
8183
n--;
@@ -84,6 +86,9 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
8486
for (i = 0; i < ARRAY_SIZE(keywords); i++) {
8587
struct keyword_entry *p = keywords + i;
8688
int len = strlen(p->keyword);
89+
90+
if (n <= len)
91+
continue;
8792
/*
8893
* Match case insensitively, so we colorize output from existing
8994
* servers regardless of the case that they use for their
@@ -101,7 +106,6 @@ static void maybe_colorize_sideband(struct strbuf *dest, const char *src, int n)
101106
}
102107

103108
strbuf_add(dest, src, n);
104-
105109
}
106110

107111

t/t5409-colorize-remote-messages.sh

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ test_expect_success 'setup' '
1515
echo warning: warning
1616
echo prefixerror: error
1717
echo " " "error: leading space"
18+
echo " "
19+
echo Err
1820
exit 0
1921
EOF
2022
echo 1 >file &&
@@ -44,6 +46,12 @@ test_expect_success 'whole words at line start' '
4446
grep "prefixerror: error" decoded
4547
'
4648

49+
test_expect_success 'short line' '
50+
git -C child -c color.remote=always push -f origin HEAD:short-line 2>output &&
51+
test_decode_color <output >decoded &&
52+
grep "remote: Err" decoded
53+
'
54+
4755
test_expect_success 'case-insensitive' '
4856
git --git-dir child/.git -c color.remote=always push -f origin HEAD:refs/heads/case-insensitive 2>output &&
4957
cat output &&
@@ -58,6 +66,12 @@ test_expect_success 'leading space' '
5866
grep " <BOLD;RED>error<RESET>: leading space" decoded
5967
'
6068

69+
test_expect_success 'spaces only' '
70+
git -C child -c color.remote=always push -f origin HEAD:only-space 2>output &&
71+
test_decode_color <output >decoded &&
72+
grep "remote: " decoded
73+
'
74+
6175
test_expect_success 'no coloring for redirected output' '
6276
git --git-dir child/.git push -f origin HEAD:refs/heads/redirected-output 2>output &&
6377
test_decode_color <output >decoded &&

0 commit comments

Comments
 (0)