@matheusbsbs / matheus-bagliano / commits / 09ded04b7e
Fork 0

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>

Nicolas Pitre committed Oct 29, 2008 at 19:02 UTC 09ded04b7e1f0096bb2fe356b2f5a298296151dd
3 files changed +13 -11
builtin-pack-objects.c
+1 -1
@@ -1002,7 +1002,7 @@ static void check_object(struct object_entry *entry)
1002 * We want in_pack_type even if we do not reuse delta
1003 * since non-delta representations could still be reused.
1004 */
1005 - used = unpack_object_header_gently(buf, avail,
1005 + used = unpack_object_header_buffer(buf, avail,
1006 &entry->in_pack_type,
1007 &entry->size);
1008
cache.h
+1 -1
@@ -754,7 +754,7 @@ extern const unsigned char *nth_packed_object_sha1(struct packed_git *, uint32_t
754 extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t);
755 extern off_t find_pack_entry_one(const unsigned char *, struct packed_git *);
756 extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
757 -extern unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
757 +extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
758 extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
759 extern const char *packed_object_info_detail(struct packed_git *, off_t, unsigned long *, unsigned long *, unsigned int *, unsigned char *);
760 extern int matches_pack_name(struct packed_git *p, const char *name);
sha1_file.c
+11 -9
@@ -1110,7 +1110,8 @@ static int legacy_loose_object(unsigned char *map)
1110 return 0;
1111 }
1112
1113 -unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep)
1113 +unsigned long unpack_object_header_buffer(const unsigned char *buf,
1114 + unsigned long len, enum object_type *type, unsigned long *sizep)
1115 {
1116 unsigned shift;
1117 unsigned char c;
@@ -1122,10 +1123,10 @@ unsigned long unpack_object_header_gently(const unsigned char *buf, unsigned lon
1123 size = c & 15;
1124 shift = 4;
1125 while (c & 0x80) {
1125 - if (len <= used)
1126 - return 0;
1127 - if (sizeof(long) * 8 <= shift)
1126 + if (len <= used || sizeof(long) * 8 <= shift) {
1127 + error("bad object header");
1128 return 0;
1129 + }
1130 c = buf[used++];
1131 size += (c & 0x7f) << shift;
1132 shift += 7;
@@ -1164,7 +1165,7 @@ static int unpack_sha1_header(z_stream *stream, unsigned char *map, unsigned lon
1165 * really worth it and we don't write it any longer. But we
1166 * can still read it.
1167 */
1167 - used = unpack_object_header_gently(map, mapsize, &type, &size);
1168 + used = unpack_object_header_buffer(map, mapsize, &type, &size);
1169 if (!used || !valid_loose_object_type[type])
1170 return -1;
1171 map += used;
@@ -1411,10 +1412,11 @@ static int unpack_object_header(struct packed_git *p,
1412 * insane, so we know won't exceed what we have been given.
1413 */
1414 base = use_pack(p, w_curs, *curpos, &left);
1414 - used = unpack_object_header_gently(base, left, &type, sizep);
1415 - if (!used)
1416 - die("object offset outside of pack file");
1417 - *curpos += used;
1415 + used = unpack_object_header_buffer(base, left, &type, sizep);
1416 + if (!used) {
1417 + type = OBJ_BAD;
1418 + } else
1419 + *curpos += used;
1420
1421 return type;
1422 }