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>
This commit is contained in:
parent
e2ffeae3f6
commit
d6a09e795d
6
delta.h
6
delta.h
@ -90,15 +90,15 @@ static inline unsigned long get_delta_hdr_size(const unsigned char **datap,
|
|||||||
const unsigned char *top)
|
const unsigned char *top)
|
||||||
{
|
{
|
||||||
const unsigned char *data = *datap;
|
const unsigned char *data = *datap;
|
||||||
unsigned long cmd, size = 0;
|
size_t cmd, size = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
do {
|
do {
|
||||||
cmd = *data++;
|
cmd = *data++;
|
||||||
size |= (cmd & 0x7f) << i;
|
size |= st_left_shift(cmd & 0x7f, i);
|
||||||
i += 7;
|
i += 7;
|
||||||
} while (cmd & 0x80 && data < top);
|
} while (cmd & 0x80 && data < top);
|
||||||
*datap = data;
|
*datap = data;
|
||||||
return size;
|
return cast_size_t_to_ulong(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1344,7 +1344,7 @@ static int parse_loose_header_extended(const char *hdr, struct object_info *oi,
|
|||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
const char *type_buf = hdr;
|
const char *type_buf = hdr;
|
||||||
unsigned long size;
|
size_t size;
|
||||||
int type, type_len = 0;
|
int type, type_len = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1388,12 +1388,12 @@ static int parse_loose_header_extended(const char *hdr, struct object_info *oi,
|
|||||||
if (c > 9)
|
if (c > 9)
|
||||||
break;
|
break;
|
||||||
hdr++;
|
hdr++;
|
||||||
size = size * 10 + c;
|
size = st_add(st_mult(size, 10), c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oi->sizep)
|
if (oi->sizep)
|
||||||
*oi->sizep = size;
|
*oi->sizep = cast_size_t_to_ulong(size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The length must be followed by a zero byte
|
* The length must be followed by a zero byte
|
||||||
|
@ -1059,7 +1059,7 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
|
|||||||
unsigned long len, enum object_type *type, unsigned long *sizep)
|
unsigned long len, enum object_type *type, unsigned long *sizep)
|
||||||
{
|
{
|
||||||
unsigned shift;
|
unsigned shift;
|
||||||
unsigned long size, c;
|
size_t size, c;
|
||||||
unsigned long used = 0;
|
unsigned long used = 0;
|
||||||
|
|
||||||
c = buf[used++];
|
c = buf[used++];
|
||||||
@ -1073,10 +1073,10 @@ unsigned long unpack_object_header_buffer(const unsigned char *buf,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
c = buf[used++];
|
c = buf[used++];
|
||||||
size += (c & 0x7f) << shift;
|
size = st_add(size, st_left_shift(c & 0x7f, shift));
|
||||||
shift += 7;
|
shift += 7;
|
||||||
}
|
}
|
||||||
*sizep = size;
|
*sizep = cast_size_t_to_ulong(size);
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user