Skip to content

Commit d5f5333

Browse files
committed
cache_name_compare(): do not truncate while comparing paths
We failed to use ce_namelen() equivalent and instead only compared up to the CE_NAMEMASK bytes by mistake. Adding an overlong path that shares the same common prefix as an existing entry in the index did not add a new entry, but instead replaced the existing one, as the result. Signed-off-by: Junio C Hamano <[email protected]>
1 parent cb198b3 commit d5f5333

File tree

2 files changed

+48
-4
lines changed

2 files changed

+48
-4
lines changed

read-cache.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,15 @@ int df_name_compare(const char *name1, int len1, int mode1,
405405

406406
int cache_name_compare(const char *name1, int flags1, const char *name2, int flags2)
407407
{
408-
int len1 = flags1 & CE_NAMEMASK;
409-
int len2 = flags2 & CE_NAMEMASK;
410-
int len = len1 < len2 ? len1 : len2;
411-
int cmp;
408+
int len1, len2, len, cmp;
409+
410+
len1 = flags1 & CE_NAMEMASK;
411+
if (CE_NAMEMASK <= len1)
412+
len1 = strlen(name1 + CE_NAMEMASK) + CE_NAMEMASK;
413+
len2 = flags2 & CE_NAMEMASK;
414+
if (CE_NAMEMASK <= len2)
415+
len2 = strlen(name2 + CE_NAMEMASK) + CE_NAMEMASK;
416+
len = len1 < len2 ? len1 : len2;
412417

413418
cmp = memcmp(name1, name2, len);
414419
if (cmp)

t/t3006-ls-files-long.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/sh
2+
3+
test_description='overly long paths'
4+
. ./test-lib.sh
5+
6+
test_expect_success setup '
7+
p=filefilefilefilefilefilefilefile &&
8+
p=$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p &&
9+
p=$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p$p &&
10+
11+
path_a=${p}_a &&
12+
path_z=${p}_z &&
13+
14+
blob_a=$(echo frotz | git hash-object -w --stdin) &&
15+
blob_z=$(echo nitfol | git hash-object -w --stdin) &&
16+
17+
pat="100644 %s 0\t%s\n"
18+
'
19+
20+
test_expect_success 'overly-long path by itself is not a problem' '
21+
printf "$pat" "$blob_a" "$path_a" |
22+
git update-index --add --index-info &&
23+
echo "$path_a" >expect &&
24+
git ls-files >actual &&
25+
test_cmp expect actual
26+
'
27+
28+
test_expect_success 'overly-long path does not replace another by mistake' '
29+
printf "$pat" "$blob_a" "$path_a" "$blob_z" "$path_z" |
30+
git update-index --add --index-info &&
31+
(
32+
echo "$path_a"
33+
echo "$path_z"
34+
) >expect &&
35+
git ls-files >actual &&
36+
test_cmp expect actual
37+
'
38+
39+
test_done

0 commit comments

Comments
 (0)