Git fork

odb: guard against data loss checking out a huge file

This introduces an additional guard for platforms where `unsigned long`
and `size_t` are not of the same size. If the size of an object in the
database would overflow `unsigned long`, instead we now exit with an
error.

A complete fix will have to update _many_ other functions throughout the
codebase to use `size_t` instead of `unsigned long`. It will have to be
implemented at some stage.

This commit puts in a stop-gap for the time being.

Helped-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Matt Cooper <vtbassmatt@gmail.com>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>

authored by vtbassmatt.tngl.sh and committed by

Junio C Hamano d6a09e79 e2ffeae3

+9 -9
+3 -3
delta.h
··· 90 90 const unsigned char *top) 91 91 { 92 92 const unsigned char *data = *datap; 93 - unsigned long cmd, size = 0; 93 + size_t cmd, size = 0; 94 94 int i = 0; 95 95 do { 96 96 cmd = *data++; 97 - size |= (cmd & 0x7f) << i; 97 + size |= st_left_shift(cmd & 0x7f, i); 98 98 i += 7; 99 99 } while (cmd & 0x80 && data < top); 100 100 *datap = data; 101 - return size; 101 + return cast_size_t_to_ulong(size); 102 102 } 103 103 104 104 #endif
+3 -3
object-file.c
··· 1344 1344 unsigned int flags) 1345 1345 { 1346 1346 const char *type_buf = hdr; 1347 - unsigned long size; 1347 + size_t size; 1348 1348 int type, type_len = 0; 1349 1349 1350 1350 /* ··· 1388 1388 if (c > 9) 1389 1389 break; 1390 1390 hdr++; 1391 - size = size * 10 + c; 1391 + size = st_add(st_mult(size, 10), c); 1392 1392 } 1393 1393 } 1394 1394 1395 1395 if (oi->sizep) 1396 - *oi->sizep = size; 1396 + *oi->sizep = cast_size_t_to_ulong(size); 1397 1397 1398 1398 /* 1399 1399 * The length must be followed by a zero byte
+3 -3
packfile.c
··· 1059 1059 unsigned long len, enum object_type *type, unsigned long *sizep) 1060 1060 { 1061 1061 unsigned shift; 1062 - unsigned long size, c; 1062 + size_t size, c; 1063 1063 unsigned long used = 0; 1064 1064 1065 1065 c = buf[used++]; ··· 1073 1073 break; 1074 1074 } 1075 1075 c = buf[used++]; 1076 - size += (c & 0x7f) << shift; 1076 + size = st_add(size, st_left_shift(c & 0x7f, shift)); 1077 1077 shift += 7; 1078 1078 } 1079 - *sizep = size; 1079 + *sizep = cast_size_t_to_ulong(size); 1080 1080 return used; 1081 1081 } 1082 1082