Browse Source

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
Nicolas Pitre 16 years ago committed by Junio C Hamano
parent
commit
09ded04b7e
  1. 2
      builtin-pack-objects.c
  2. 2
      cache.h
  3. 20
      sha1_file.c

2
builtin-pack-objects.c

@ -1002,7 +1002,7 @@ static void check_object(struct object_entry *entry) @@ -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

@ -754,7 +754,7 @@ extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t @@ -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);

20
sha1_file.c

@ -1110,7 +1110,8 @@ static int legacy_loose_object(unsigned char *map) @@ -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 @@ -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 @@ -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,10 +1412,11 @@ static int unpack_object_header(struct packed_git *p, @@ -1411,10 +1412,11 @@ 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");
*curpos += used;
used = unpack_object_header_buffer(base, left, &type, sizep);
if (!used) {
type = OBJ_BAD;
} else
*curpos += used;

return type;
}

Loading…
Cancel
Save