Skip to content

Commit d6a09e7

Browse files
vtbassmattgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Matt Cooper <[email protected]> Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e2ffeae commit d6a09e7

File tree

3 files changed

+9
-9
lines changed

3 files changed

+9
-9
lines changed

delta.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ static inline unsigned long get_delta_hdr_size(const unsigned char **datap,
9090
const unsigned char *top)
9191
{
9292
const unsigned char *data = *datap;
93-
unsigned long cmd, size = 0;
93+
size_t cmd, size = 0;
9494
int i = 0;
9595
do {
9696
cmd = *data++;
97-
size |= (cmd & 0x7f) << i;
97+
size |= st_left_shift(cmd & 0x7f, i);
9898
i += 7;
9999
} while (cmd & 0x80 && data < top);
100100
*datap = data;
101-
return size;
101+
return cast_size_t_to_ulong(size);
102102
}
103103

104104
#endif

object-file.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ static int parse_loose_header_extended(const char *hdr, struct object_info *oi,
13441344
unsigned int flags)
13451345
{
13461346
const char *type_buf = hdr;
1347-
unsigned long size;
1347+
size_t size;
13481348
int type, type_len = 0;
13491349

13501350
/*
@@ -1388,12 +1388,12 @@ static int parse_loose_header_extended(const char *hdr, struct object_info *oi,
13881388
if (c > 9)
13891389
break;
13901390
hdr++;
1391-
size = size * 10 + c;
1391+
size = st_add(st_mult(size, 10), c);
13921392
}
13931393
}
13941394

13951395
if (oi->sizep)
1396-
*oi->sizep = size;
1396+
*oi->sizep = cast_size_t_to_ulong(size);
13971397

13981398
/*
13991399
* The length must be followed by a zero byte

packfile.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
10591059
unsigned long len, enum object_type *type, unsigned long *sizep)
10601060
{
10611061
unsigned shift;
1062-
unsigned long size, c;
1062+
size_t size, c;
10631063
unsigned long used = 0;
10641064

10651065
c = buf[used++];
@@ -1073,10 +1073,10 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
10731073
break;
10741074
}
10751075
c = buf[used++];
1076-
size += (c & 0x7f) << shift;
1076+
size = st_add(size, st_left_shift(c & 0x7f, shift));
10771077
shift += 7;
10781078
}
1079-
*sizep = size;
1079+
*sizep = cast_size_t_to_ulong(size);
10801080
return used;
10811081
}
10821082

0 commit comments

Comments
 (0)