make unpack_object_header() non fatal
It is possible to have pack corruption in the object header. Currently unpack_object_header() simply die() on them instead of letting the caller deal with that gracefully. So let's have unpack_object_header() return an error instead, and find a better name for unpack_object_header_gently() in that context. All callers of unpack_object_header() are ready for it. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
d8f325563d
commit
09ded04b7e
@ -1002,7 +1002,7 @@ static void check_object(struct object_entry *entry)
|
||||
* We want in_pack_type even if we do not reuse delta
|
||||
* since non-delta representations could still be reused.
|
||||
*/
|
||||
used = unpack_object_header_gently(buf, avail,
|
||||
used = unpack_object_header_buffer(buf, avail,
|
||||
&entry->in_pack_type,
|
||||
&entry->size);
|
||||
|
||||
|
2
cache.h
2
cache.h
@ -754,7 +754,7 @@ extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t
|
||||
extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t);
|
||||
extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
|
||||
extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
|
||||
extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
|
||||
extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
|
||||
extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
|
||||
extern const char *packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
|
||||
extern int matches_pack_name(struct packed_git *p, const char *name);
|
||||
|
18
sha1_file.c
18
sha1_file.c
@ -1110,7 +1110,8 @@ static int legacy_loose_object(unsigned char *map)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep)
|
||||
unsigned long unpack_object_header_buffer(const unsigned char *buf,
|
||||
unsigned long len, enum object_type *type, unsigned long *sizep)
|
||||
{
|
||||
unsigned shift;
|
||||
unsigned char c;
|
||||
@ -1122,10 +1123,10 @@ unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned lon
|
||||
size = c & 15;
|
||||
shift = 4;
|
||||
while (c & 0x80) {
|
||||
if (len <= used)
|
||||
return 0;
|
||||
if (sizeof(long) * 8 <= shift)
|
||||
if (len <= used || sizeof(long) * 8 <= shift) {
|
||||
error("bad object header");
|
||||
return 0;
|
||||
}
|
||||
c = buf[used++];
|
||||
size += (c & 0x7f) << shift;
|
||||
shift += 7;
|
||||
@ -1164,7 +1165,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
|
||||
* really worth it and we don't write it any longer. But we
|
||||
* can still read it.
|
||||
*/
|
||||
used = unpack_object_header_gently(map, mapsize, &type, &size);
|
||||
used = unpack_object_header_buffer(map, mapsize, &type, &size);
|
||||
if (!used || !valid_loose_object_type[type])
|
||||
return -1;
|
||||
map += used;
|
||||
@ -1411,9 +1412,10 @@ static int unpack_object_header(struct packed_git *p,
|
||||
* insane, so we know won't exceed what we have been given.
|
||||
*/
|
||||
base = use_pack(p, w_curs, *curpos, &left);
|
||||
used = unpack_object_header_gently(base, left, &type, sizep);
|
||||
if (!used)
|
||||
die("object offset outside of pack file");
|
||||
used = unpack_object_header_buffer(base, left, &type, sizep);
|
||||
if (!used) {
|
||||
type = OBJ_BAD;
|
||||
} else
|
||||
*curpos += used;
|
||||
|
||||
return type;
|
||||
|
Loading…
Reference in New Issue
Block a user