Skip to content

Commit f0e7f11

Browse files
peffgitster
authored andcommitted
index-pack: fix truncation of off_t in comparison
Commit c6458e6 (index-pack: kill union delta_base to save memory, 2015-04-18) refactored the comparison functions used in sorting and binary searching our delta list. The resulting code does something like: int cmp_offsets(off_t a, off_t b) { return a - b; } This works most of the time, but produces nonsensical results when the difference between the two offsets is larger than what can be stored in an "int". This can lead to unresolved deltas if the packsize is larger than 2G (even on 64-bit systems, an int is still typically 32 bits): $ git clone git://github.com/mozilla/gecko-dev Cloning into 'gecko-dev'... remote: Counting objects: 4800161, done. remote: Compressing objects: 100% (178/178), done. remote: Total 4800161 (delta 88), reused 0 (delta 0), pack-reused 4799978 Receiving objects: 100% (4800161/4800161), 2.21 GiB | 3.26 MiB/s, done. Resolving deltas: 99% (3808820/3811944), completed with 0 local objects. fatal: pack has 3124 unresolved deltas fatal: index-pack failed We can fix it by doing direct comparisons between the offsets and returning constants; the callers only care about the sign of the comparison, not the magnitude. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c6458e6 commit f0e7f11

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

builtin/index-pack.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,9 @@ static int compare_ofs_delta_bases(off_t offset1, off_t offset2,
616616
int cmp = type1 - type2;
617617
if (cmp)
618618
return cmp;
619-
return offset1 - offset2;
619+
return offset1 < offset2 ? -1 :
620+
offset1 > offset2 ? 1 :
621+
0;
620622
}
621623

622624
static int find_ofs_delta(const off_t offset, enum object_type type)
@@ -1051,7 +1053,9 @@ static int compare_ofs_delta_entry(const void *a, const void *b)
10511053
const struct ofs_delta_entry *delta_a = a;
10521054
const struct ofs_delta_entry *delta_b = b;
10531055

1054-
return delta_a->offset - delta_b->offset;
1056+
return delta_a->offset < delta_b->offset ? -1 :
1057+
delta_a->offset > delta_b->offset ? 1 :
1058+
0;
10551059
}
10561060

10571061
static int compare_ref_delta_entry(const void *a, const void *b)

0 commit comments

Comments
 (0)