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>maint
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
|
* We want in_pack_type even if we do not reuse delta
|
||||||
* since non-delta representations could still be reused.
|
* 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->in_pack_type,
|
||||||
&entry->size);
|
&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 nth_packed_object_offset(const struct packed_git *, uint32_t);
|
||||||
extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
|
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 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 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 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);
|
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;
|
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 shift;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
|
@ -1122,10 +1123,10 @@ unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned lon
|
||||||
size = c & 15;
|
size = c & 15;
|
||||||
shift = 4;
|
shift = 4;
|
||||||
while (c & 0x80) {
|
while (c & 0x80) {
|
||||||
if (len <= used)
|
if (len <= used || sizeof(long) * 8 <= shift) {
|
||||||
return 0;
|
error("bad object header");
|
||||||
if (sizeof(long) * 8 <= shift)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
c = buf[used++];
|
c = buf[used++];
|
||||||
size += (c & 0x7f) << shift;
|
size += (c & 0x7f) << shift;
|
||||||
shift += 7;
|
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
|
* really worth it and we don't write it any longer. But we
|
||||||
* can still read it.
|
* 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])
|
if (!used || !valid_loose_object_type[type])
|
||||||
return -1;
|
return -1;
|
||||||
map += used;
|
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.
|
* insane, so we know won't exceed what we have been given.
|
||||||
*/
|
*/
|
||||||
base = use_pack(p, w_curs, *curpos, &left);
|
base = use_pack(p, w_curs, *curpos, &left);
|
||||||
used = unpack_object_header_gently(base, left, &type, sizep);
|
used = unpack_object_header_buffer(base, left, &type, sizep);
|
||||||
if (!used)
|
if (!used) {
|
||||||
die("object offset outside of pack file");
|
type = OBJ_BAD;
|
||||||
|
} else
|
||||||
*curpos += used;
|
*curpos += used;
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
|
|
Loading…
Reference in New Issue