Skip to content

Commit 8424981

Browse files
peffgitster
authored andcommitted
Fix invalid read in quote_c_style_counted
This function did not work on strings that were not NUL-terminated. It reads through a length-bounded string, searching for characters in need of quoting. After we find one, we output the quoted character, then advance our pointer to find the next one. However, we never decremented the length, meaning we ended up looking at whatever random junk was stored after the string. This bug was not found by the existing tests because most code paths feed a NUL-terminated string. The notable exception is a directory name being fed by ls-tree. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d2d66f1 commit 8424981

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

quote.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
213213
int ch;
214214

215215
len = next_quote_pos(p, maxlen);
216-
if (len == maxlen || !p[len])
216+
if (len == maxlen || (maxlen < 0 && !p[len]))
217217
break;
218218

219219
if (!no_dq && p == name)
@@ -223,6 +223,8 @@ static size_t quote_c_style_counted(const char *name, ssize_t maxlen,
223223
EMIT('\\');
224224
p += len;
225225
ch = (unsigned char)*p++;
226+
if (maxlen >= 0)
227+
maxlen -= len + 1;
226228
if (sq_lookup[ch] >= ' ') {
227229
EMIT(sq_lookup[ch]);
228230
} else {

t/t3902-quoted.sh

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ for_each_name () {
2525
for name in \
2626
Name "Name and a${LF}LF" "Name and an${HT}HT" "Name${DQ}" \
2727
"$FN$HT$GN" "$FN$LF$GN" "$FN $GN" "$FN$GN" "$FN$DQ$GN" \
28-
"With SP in it"
28+
"With SP in it" "caractère spécial/file"
2929
do
3030
eval "$1"
3131
done
3232
}
3333

3434
test_expect_success setup '
3535
36+
mkdir "caractère spécial" &&
3637
for_each_name "echo initial >\"\$name\""
3738
git add . &&
3839
git commit -q -m Initial &&
@@ -50,6 +51,7 @@ Name
5051
"Name and an\tHT"
5152
"Name\""
5253
With SP in it
54+
"caract\303\250re sp\303\251cial/file"
5355
"\346\277\261\351\207\216\t\347\264\224"
5456
"\346\277\261\351\207\216\n\347\264\224"
5557
"\346\277\261\351\207\216 \347\264\224"
@@ -63,6 +65,7 @@ Name
6365
"Name and an\tHT"
6466
"Name\""
6567
With SP in it
68+
caractère spécial/file
6669
"濱野\t純"
6770
"濱野\n純"
6871
濱野 純
@@ -97,6 +100,13 @@ test_expect_success 'check fully quoted output from diff-tree' '
97100
98101
'
99102

103+
test_expect_success 'check fully quoted output from ls-tree' '
104+
105+
git ls-tree --name-only -r HEAD >current &&
106+
test_cmp expect.quoted current
107+
108+
'
109+
100110
test_expect_success 'setting core.quotepath' '
101111
102112
git config --bool core.quotepath false
@@ -130,4 +140,11 @@ test_expect_success 'check fully quoted output from diff-tree' '
130140
131141
'
132142

143+
test_expect_success 'check fully quoted output from ls-tree' '
144+
145+
git ls-tree --name-only -r HEAD >current &&
146+
test_cmp expect.raw current
147+
148+
'
149+
133150
test_done

0 commit comments

Comments
 (0)