make check_object() resilient to pack corruptions
The check_object() function tries to get away with the least amount of pack access possible when it already has partial information on given object rather than calling the more costly packed_object_info(). When things don't look right, it should just give up and fall back to packed_object_info() directly instead of die()'ing. 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
03d660150cbc80cd7d2ec90c3c4e6ce563295e3a
1 file changed
+17
-6
builtin-pack-objects.c
+17
-6
@@ -1005,6 +1005,8 @@ static void check_object(struct object_entry *entry)
1005
used = unpack_object_header_buffer(buf, avail,
1006
&entry->in_pack_type,
1007
&entry->size);
1008
+ if (used == 0)
1009
+ goto give_up;
1010
1011
/*
1012
* Determine if this is a delta and if so whether we can
@@ -1016,6 +1018,8 @@ static void check_object(struct object_entry *entry)
1018
/* Not a delta hence we've already got all we need. */
1019
entry->type = entry->in_pack_type;
1020
entry->in_pack_header_size = used;
1021
+ if (entry->type < OBJ_COMMIT || entry->type > OBJ_BLOB)
1022
+ goto give_up;
1023
unuse_pack(&w_curs);
1024
return;
1025
case OBJ_REF_DELTA:
@@ -1032,16 +1036,20 @@ static void check_object(struct object_entry *entry)
1036
ofs = c & 127;
1037
while (c & 128) {
1038
ofs += 1;
1035
- if (!ofs || MSB(ofs, 7))
1036
- die("delta base offset overflow in pack for %s",
1037
- sha1_to_hex(entry->idx.sha1));
1039
+ if (!ofs || MSB(ofs, 7)) {
1040
+ error("delta base offset overflow in pack for %s",
1041
+ sha1_to_hex(entry->idx.sha1));
1042
+ goto give_up;
1043
+ }
1044
c = buf[used_0++];
1045
ofs = (ofs << 7) + (c & 127);
1046
}
1047
ofs = entry->in_pack_offset - ofs;
1042
- if (ofs <= 0 || ofs >= entry->in_pack_offset)
1043
- die("delta base offset out of bound for %s",
1044
- sha1_to_hex(entry->idx.sha1));
1048
+ if (ofs <= 0 || ofs >= entry->in_pack_offset) {
1049
+ error("delta base offset out of bound for %s",
1050
+ sha1_to_hex(entry->idx.sha1));
1051
+ goto give_up;
1052
+ }
1053
if (reuse_delta && !entry->preferred_base) {
1054
struct revindex_entry *revidx;
1055
revidx = find_pack_revindex(p, ofs);
@@ -1078,6 +1086,8 @@ static void check_object(struct object_entry *entry)
1086
*/
1087
entry->size = get_size_from_delta(p, &w_curs,
1088
entry->in_pack_offset + entry->in_pack_header_size);
1089
+ if (entry->size == 0)
1090
+ goto give_up;
1091
unuse_pack(&w_curs);
1092
return;
1093
}
@@ -1087,6 +1097,7 @@ static void check_object(struct object_entry *entry)
1097
* with sha1_object_info() to find about the object type
1098
* at this point...
1099
*/
1100
+ give_up:
1101
unuse_pack(&w_curs);
1102
}
1103