提交 09ded04b 编写于 作者: N Nicolas Pitre 提交者: Junio C Hamano

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: NNicolas Pitre <nico@cam.org>
Signed-off-by: NJunio C Hamano <gitster@pobox.com>
上级 d8f32556
...@@ -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 * 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);
......
...@@ -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 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);
......
...@@ -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; 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 ...@@ -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 ...@@ -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,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. * 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;
*curpos += used; } else
*curpos += used;
return type; return type;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册