@matheusbsbs / matheus-bagliano / commits / 03d660150c
Fork 0

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