pack: move clear_delta_base_cache(), packed_object_info(), unpack_entry()

Both sha1_file.c and packfile.c now need read_object(), so a copy of read_object() was created in packfile.c. This patch makes both mark_bad_packed_object() and has_packed_and_bad() global. Unlike most of the other patches in this series, these 2 functions need to remain global. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Tan committed Aug 18, 2017 at 15:20 UTC f1d8130be0a7229b215b76eac54c561a0124bc99
4 files changed +685 -670
cache.h
-7
@@ -1187,9 +1187,6 @@ extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
1187 extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
1188 extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
1189
1190 -/* global flag to enable extra checks when accessing packed objects */
1191 -extern int do_check_packed_object_crc;
1192 -
1190 extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
1191
1192 extern int finalize_object_file(const char *tmpfile, const char *filename);
@@ -1623,8 +1620,6 @@ extern int odb_mkstemp(struct strbuf *template, const char *pattern);
1620 */
1621 extern int odb_pack_keep(const char *name);
1622
1626 -extern void clear_delta_base_cache(void);
1627 -
1623 /*
1624 * Make sure that a pointer access into an mmap'd index file is within bounds,
1625 * and can provide at least 8 bytes of data.
@@ -1662,7 +1657,6 @@ extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t n);
1657 extern off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *);
1658
1659 extern int is_pack_valid(struct packed_git *);
1665 -extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
1660
1661 /*
1662 * Iterate over the files in the loose-object parts of the object
@@ -1773,7 +1767,6 @@ struct object_info {
1767 /* Do not retry packed storage after checking packed and loose storage */
1768 #define OBJECT_INFO_QUICK 8
1769 extern int sha1_object_info_extended(const unsigned char *, struct object_info *, unsigned flags);
1776 -extern int packed_object_info(struct packed_git *pack, off_t offset, struct object_info *);
1770
1771 /* Dumb servers support */
1772 extern int update_server_info(int);
packfile.c
+661
@@ -5,6 +5,8 @@
5 #include "mergesort.h"
6 #include "packfile.h"
7 #include "delta.h"
8 +#include "list.h"
9 +#include "streaming.h"
10
11 char *odb_pack_name(struct strbuf *buf,
12 const unsigned char *sha1,
@@ -975,3 +977,662 @@ int unpack_object_header(struct packed_git *p,
977
978 return type;
979 }
980 +
981 +void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1)
982 +{
983 + unsigned i;
984 + for (i = 0; i < p->num_bad_objects; i++)
985 + if (!hashcmp(sha1, p->bad_object_sha1 + GIT_SHA1_RAWSZ * i))
986 + return;
987 + p->bad_object_sha1 = xrealloc(p->bad_object_sha1,
988 + st_mult(GIT_MAX_RAWSZ,
989 + st_add(p->num_bad_objects, 1)));
990 + hashcpy(p->bad_object_sha1 + GIT_SHA1_RAWSZ * p->num_bad_objects, sha1);
991 + p->num_bad_objects++;
992 +}
993 +
994 +const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
995 +{
996 + struct packed_git *p;
997 + unsigned i;
998 +
999 + for (p = packed_git; p; p = p->next)
1000 + for (i = 0; i < p->num_bad_objects; i++)
1001 + if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
1002 + return p;
1003 + return NULL;
1004 +}
1005 +
1006 +static off_t get_delta_base(struct packed_git *p,
1007 + struct pack_window **w_curs,
1008 + off_t *curpos,
1009 + enum object_type type,
1010 + off_t delta_obj_offset)
1011 +{
1012 + unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL);
1013 + off_t base_offset;
1014 +
1015 + /* use_pack() assured us we have [base_info, base_info + 20)
1016 + * as a range that we can look at without walking off the
1017 + * end of the mapped window. Its actually the hash size
1018 + * that is assured. An OFS_DELTA longer than the hash size
1019 + * is stupid, as then a REF_DELTA would be smaller to store.
1020 + */
1021 + if (type == OBJ_OFS_DELTA) {
1022 + unsigned used = 0;
1023 + unsigned char c = base_info[used++];
1024 + base_offset = c & 127;
1025 + while (c & 128) {
1026 + base_offset += 1;
1027 + if (!base_offset || MSB(base_offset, 7))
1028 + return 0; /* overflow */
1029 + c = base_info[used++];
1030 + base_offset = (base_offset << 7) + (c & 127);
1031 + }
1032 + base_offset = delta_obj_offset - base_offset;
1033 + if (base_offset <= 0 || base_offset >= delta_obj_offset)
1034 + return 0; /* out of bound */
1035 + *curpos += used;
1036 + } else if (type == OBJ_REF_DELTA) {
1037 + /* The base entry _must_ be in the same pack */
1038 + base_offset = find_pack_entry_one(base_info, p);
1039 + *curpos += 20;
1040 + } else
1041 + die("I am totally screwed");
1042 + return base_offset;
1043 +}
1044 +
1045 +/*
1046 + * Like get_delta_base above, but we return the sha1 instead of the pack
1047 + * offset. This means it is cheaper for REF deltas (we do not have to do
1048 + * the final object lookup), but more expensive for OFS deltas (we
1049 + * have to load the revidx to convert the offset back into a sha1).
1050 + */
1051 +static const unsigned char *get_delta_base_sha1(struct packed_git *p,
1052 + struct pack_window **w_curs,
1053 + off_t curpos,
1054 + enum object_type type,
1055 + off_t delta_obj_offset)
1056 +{
1057 + if (type == OBJ_REF_DELTA) {
1058 + unsigned char *base = use_pack(p, w_curs, curpos, NULL);
1059 + return base;
1060 + } else if (type == OBJ_OFS_DELTA) {
1061 + struct revindex_entry *revidx;
1062 + off_t base_offset = get_delta_base(p, w_curs, &curpos,
1063 + type, delta_obj_offset);
1064 +
1065 + if (!base_offset)
1066 + return NULL;
1067 +
1068 + revidx = find_pack_revindex(p, base_offset);
1069 + if (!revidx)
1070 + return NULL;
1071 +
1072 + return nth_packed_object_sha1(p, revidx->nr);
1073 + } else
1074 + return NULL;
1075 +}
1076 +
1077 +static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
1078 +{
1079 + int type;
1080 + struct revindex_entry *revidx;
1081 + const unsigned char *sha1;
1082 + revidx = find_pack_revindex(p, obj_offset);
1083 + if (!revidx)
1084 + return OBJ_BAD;
1085 + sha1 = nth_packed_object_sha1(p, revidx->nr);
1086 + mark_bad_packed_object(p, sha1);
1087 + type = sha1_object_info(sha1, NULL);
1088 + if (type <= OBJ_NONE)
1089 + return OBJ_BAD;
1090 + return type;
1091 +}
1092 +
1093 +#define POI_STACK_PREALLOC 64
1094 +
1095 +static enum object_type packed_to_object_type(struct packed_git *p,
1096 + off_t obj_offset,
1097 + enum object_type type,
1098 + struct pack_window **w_curs,
1099 + off_t curpos)
1100 +{
1101 + off_t small_poi_stack[POI_STACK_PREALLOC];
1102 + off_t *poi_stack = small_poi_stack;
1103 + int poi_stack_nr = 0, poi_stack_alloc = POI_STACK_PREALLOC;
1104 +
1105 + while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1106 + off_t base_offset;
1107 + unsigned long size;
1108 + /* Push the object we're going to leave behind */
1109 + if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) {
1110 + poi_stack_alloc = alloc_nr(poi_stack_nr);
1111 + ALLOC_ARRAY(poi_stack, poi_stack_alloc);
1112 + memcpy(poi_stack, small_poi_stack, sizeof(off_t)*poi_stack_nr);
1113 + } else {
1114 + ALLOC_GROW(poi_stack, poi_stack_nr+1, poi_stack_alloc);
1115 + }
1116 + poi_stack[poi_stack_nr++] = obj_offset;
1117 + /* If parsing the base offset fails, just unwind */
1118 + base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
1119 + if (!base_offset)
1120 + goto unwind;
1121 + curpos = obj_offset = base_offset;
1122 + type = unpack_object_header(p, w_curs, &curpos, &size);
1123 + if (type <= OBJ_NONE) {
1124 + /* If getting the base itself fails, we first
1125 + * retry the base, otherwise unwind */
1126 + type = retry_bad_packed_offset(p, base_offset);
1127 + if (type > OBJ_NONE)
1128 + goto out;
1129 + goto unwind;
1130 + }
1131 + }
1132 +
1133 + switch (type) {
1134 + case OBJ_BAD:
1135 + case OBJ_COMMIT:
1136 + case OBJ_TREE:
1137 + case OBJ_BLOB:
1138 + case OBJ_TAG:
1139 + break;
1140 + default:
1141 + error("unknown object type %i at offset %"PRIuMAX" in %s",
1142 + type, (uintmax_t)obj_offset, p->pack_name);
1143 + type = OBJ_BAD;
1144 + }
1145 +
1146 +out:
1147 + if (poi_stack != small_poi_stack)
1148 + free(poi_stack);
1149 + return type;
1150 +
1151 +unwind:
1152 + while (poi_stack_nr) {
1153 + obj_offset = poi_stack[--poi_stack_nr];
1154 + type = retry_bad_packed_offset(p, obj_offset);
1155 + if (type > OBJ_NONE)
1156 + goto out;
1157 + }
1158 + type = OBJ_BAD;
1159 + goto out;
1160 +}
1161 +
1162 +static struct hashmap delta_base_cache;
1163 +static size_t delta_base_cached;
1164 +
1165 +static LIST_HEAD(delta_base_cache_lru);
1166 +
1167 +struct delta_base_cache_key {
1168 + struct packed_git *p;
1169 + off_t base_offset;
1170 +};
1171 +
1172 +struct delta_base_cache_entry {
1173 + struct hashmap hash;
1174 + struct delta_base_cache_key key;
1175 + struct list_head lru;
1176 + void *data;
1177 + unsigned long size;
1178 + enum object_type type;
1179 +};
1180 +
1181 +static unsigned int pack_entry_hash(struct packed_git *p, off_t base_offset)
1182 +{
1183 + unsigned int hash;
1184 +
1185 + hash = (unsigned int)(intptr_t)p + (unsigned int)base_offset;
1186 + hash += (hash >> 8) + (hash >> 16);
1187 + return hash;
1188 +}
1189 +
1190 +static struct delta_base_cache_entry *
1191 +get_delta_base_cache_entry(struct packed_git *p, off_t base_offset)
1192 +{
1193 + struct hashmap_entry entry;
1194 + struct delta_base_cache_key key;
1195 +
1196 + if (!delta_base_cache.cmpfn)
1197 + return NULL;
1198 +
1199 + hashmap_entry_init(&entry, pack_entry_hash(p, base_offset));
1200 + key.p = p;
1201 + key.base_offset = base_offset;
1202 + return hashmap_get(&delta_base_cache, &entry, &key);
1203 +}
1204 +
1205 +static int delta_base_cache_key_eq(const struct delta_base_cache_key *a,
1206 + const struct delta_base_cache_key *b)
1207 +{
1208 + return a->p == b->p && a->base_offset == b->base_offset;
1209 +}
1210 +
1211 +static int delta_base_cache_hash_cmp(const void *unused_cmp_data,
1212 + const void *va, const void *vb,
1213 + const void *vkey)
1214 +{
1215 + const struct delta_base_cache_entry *a = va, *b = vb;
1216 + const struct delta_base_cache_key *key = vkey;
1217 + if (key)
1218 + return !delta_base_cache_key_eq(&a->key, key);
1219 + else
1220 + return !delta_base_cache_key_eq(&a->key, &b->key);
1221 +}
1222 +
1223 +static int in_delta_base_cache(struct packed_git *p, off_t base_offset)
1224 +{
1225 + return !!get_delta_base_cache_entry(p, base_offset);
1226 +}
1227 +
1228 +/*
1229 + * Remove the entry from the cache, but do _not_ free the associated
1230 + * entry data. The caller takes ownership of the "data" buffer, and
1231 + * should copy out any fields it wants before detaching.
1232 + */
1233 +static void detach_delta_base_cache_entry(struct delta_base_cache_entry *ent)
1234 +{
1235 + hashmap_remove(&delta_base_cache, ent, &ent->key);
1236 + list_del(&ent->lru);
1237 + delta_base_cached -= ent->size;
1238 + free(ent);
1239 +}
1240 +
1241 +static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
1242 + unsigned long *base_size, enum object_type *type)
1243 +{
1244 + struct delta_base_cache_entry *ent;
1245 +
1246 + ent = get_delta_base_cache_entry(p, base_offset);
1247 + if (!ent)
1248 + return unpack_entry(p, base_offset, type, base_size);
1249 +
1250 + if (type)
1251 + *type = ent->type;
1252 + if (base_size)
1253 + *base_size = ent->size;
1254 + return xmemdupz(ent->data, ent->size);
1255 +}
1256 +
1257 +static inline void release_delta_base_cache(struct delta_base_cache_entry *ent)
1258 +{
1259 + free(ent->data);
1260 + detach_delta_base_cache_entry(ent);
1261 +}
1262 +
1263 +void clear_delta_base_cache(void)
1264 +{
1265 + struct list_head *lru, *tmp;
1266 + list_for_each_safe(lru, tmp, &delta_base_cache_lru) {
1267 + struct delta_base_cache_entry *entry =
1268 + list_entry(lru, struct delta_base_cache_entry, lru);
1269 + release_delta_base_cache(entry);
1270 + }
1271 +}
1272 +
1273 +static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
1274 + void *base, unsigned long base_size, enum object_type type)
1275 +{
1276 + struct delta_base_cache_entry *ent = xmalloc(sizeof(*ent));
1277 + struct list_head *lru, *tmp;
1278 +
1279 + delta_base_cached += base_size;
1280 +
1281 + list_for_each_safe(lru, tmp, &delta_base_cache_lru) {
1282 + struct delta_base_cache_entry *f =
1283 + list_entry(lru, struct delta_base_cache_entry, lru);
1284 + if (delta_base_cached <= delta_base_cache_limit)
1285 + break;
1286 + release_delta_base_cache(f);
1287 + }
1288 +
1289 + ent->key.p = p;
1290 + ent->key.base_offset = base_offset;
1291 + ent->type = type;
1292 + ent->data = base;
1293 + ent->size = base_size;
1294 + list_add_tail(&ent->lru, &delta_base_cache_lru);
1295 +
1296 + if (!delta_base_cache.cmpfn)
1297 + hashmap_init(&delta_base_cache, delta_base_cache_hash_cmp, NULL, 0);
1298 + hashmap_entry_init(ent, pack_entry_hash(p, base_offset));
1299 + hashmap_add(&delta_base_cache, ent);
1300 +}
1301 +
1302 +int packed_object_info(struct packed_git *p, off_t obj_offset,
1303 + struct object_info *oi)
1304 +{
1305 + struct pack_window *w_curs = NULL;
1306 + unsigned long size;
1307 + off_t curpos = obj_offset;
1308 + enum object_type type;
1309 +
1310 + /*
1311 + * We always get the representation type, but only convert it to
1312 + * a "real" type later if the caller is interested.
1313 + */
1314 + if (oi->contentp) {
1315 + *oi->contentp = cache_or_unpack_entry(p, obj_offset, oi->sizep,
1316 + &type);
1317 + if (!*oi->contentp)
1318 + type = OBJ_BAD;
1319 + } else {
1320 + type = unpack_object_header(p, &w_curs, &curpos, &size);
1321 + }
1322 +
1323 + if (!oi->contentp && oi->sizep) {
1324 + if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1325 + off_t tmp_pos = curpos;
1326 + off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
1327 + type, obj_offset);
1328 + if (!base_offset) {
1329 + type = OBJ_BAD;
1330 + goto out;
1331 + }
1332 + *oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos);
1333 + if (*oi->sizep == 0) {
1334 + type = OBJ_BAD;
1335 + goto out;
1336 + }
1337 + } else {
1338 + *oi->sizep = size;
1339 + }
1340 + }
1341 +
1342 + if (oi->disk_sizep) {
1343 + struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
1344 + *oi->disk_sizep = revidx[1].offset - obj_offset;
1345 + }
1346 +
1347 + if (oi->typep || oi->typename) {
1348 + enum object_type ptot;
1349 + ptot = packed_to_object_type(p, obj_offset, type, &w_curs,
1350 + curpos);
1351 + if (oi->typep)
1352 + *oi->typep = ptot;
1353 + if (oi->typename) {
1354 + const char *tn = typename(ptot);
1355 + if (tn)
1356 + strbuf_addstr(oi->typename, tn);
1357 + }
1358 + if (ptot < 0) {
1359 + type = OBJ_BAD;
1360 + goto out;
1361 + }
1362 + }
1363 +
1364 + if (oi->delta_base_sha1) {
1365 + if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1366 + const unsigned char *base;
1367 +
1368 + base = get_delta_base_sha1(p, &w_curs, curpos,
1369 + type, obj_offset);
1370 + if (!base) {
1371 + type = OBJ_BAD;
1372 + goto out;
1373 + }
1374 +
1375 + hashcpy(oi->delta_base_sha1, base);
1376 + } else
1377 + hashclr(oi->delta_base_sha1);
1378 + }
1379 +
1380 + oi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED :
1381 + OI_PACKED;
1382 +
1383 +out:
1384 + unuse_pack(&w_curs);
1385 + return type;
1386 +}
1387 +
1388 +static void *unpack_compressed_entry(struct packed_git *p,
1389 + struct pack_window **w_curs,
1390 + off_t curpos,
1391 + unsigned long size)
1392 +{
1393 + int st;
1394 + git_zstream stream;
1395 + unsigned char *buffer, *in;
1396 +
1397 + buffer = xmallocz_gently(size);
1398 + if (!buffer)
1399 + return NULL;
1400 + memset(&stream, 0, sizeof(stream));
1401 + stream.next_out = buffer;
1402 + stream.avail_out = size + 1;
1403 +
1404 + git_inflate_init(&stream);
1405 + do {
1406 + in = use_pack(p, w_curs, curpos, &stream.avail_in);
1407 + stream.next_in = in;
1408 + st = git_inflate(&stream, Z_FINISH);
1409 + if (!stream.avail_out)
1410 + break; /* the payload is larger than it should be */
1411 + curpos += stream.next_in - in;
1412 + } while (st == Z_OK || st == Z_BUF_ERROR);
1413 + git_inflate_end(&stream);
1414 + if ((st != Z_STREAM_END) || stream.total_out != size) {
1415 + free(buffer);
1416 + return NULL;
1417 + }
1418 +
1419 + return buffer;
1420 +}
1421 +
1422 +static void write_pack_access_log(struct packed_git *p, off_t obj_offset)
1423 +{
1424 + static struct trace_key pack_access = TRACE_KEY_INIT(PACK_ACCESS);
1425 + trace_printf_key(&pack_access, "%s %"PRIuMAX"\n",
1426 + p->pack_name, (uintmax_t)obj_offset);
1427 +}
1428 +
1429 +int do_check_packed_object_crc;
1430 +
1431 +#define UNPACK_ENTRY_STACK_PREALLOC 64
1432 +struct unpack_entry_stack_ent {
1433 + off_t obj_offset;
1434 + off_t curpos;
1435 + unsigned long size;
1436 +};
1437 +
1438 +static void *read_object(const unsigned char *sha1, enum object_type *type,
1439 + unsigned long *size)
1440 +{
1441 + struct object_info oi = OBJECT_INFO_INIT;
1442 + void *content;
1443 + oi.typep = type;
1444 + oi.sizep = size;
1445 + oi.contentp = &content;
1446 +
1447 + if (sha1_object_info_extended(sha1, &oi, 0) < 0)
1448 + return NULL;
1449 + return content;
1450 +}
1451 +
1452 +void *unpack_entry(struct packed_git *p, off_t obj_offset,
1453 + enum object_type *final_type, unsigned long *final_size)
1454 +{
1455 + struct pack_window *w_curs = NULL;
1456 + off_t curpos = obj_offset;
1457 + void *data = NULL;
1458 + unsigned long size;
1459 + enum object_type type;
1460 + struct unpack_entry_stack_ent small_delta_stack[UNPACK_ENTRY_STACK_PREALLOC];
1461 + struct unpack_entry_stack_ent *delta_stack = small_delta_stack;
1462 + int delta_stack_nr = 0, delta_stack_alloc = UNPACK_ENTRY_STACK_PREALLOC;
1463 + int base_from_cache = 0;
1464 +
1465 + write_pack_access_log(p, obj_offset);
1466 +
1467 + /* PHASE 1: drill down to the innermost base object */
1468 + for (;;) {
1469 + off_t base_offset;
1470 + int i;
1471 + struct delta_base_cache_entry *ent;
1472 +
1473 + ent = get_delta_base_cache_entry(p, curpos);
1474 + if (ent) {
1475 + type = ent->type;
1476 + data = ent->data;
1477 + size = ent->size;
1478 + detach_delta_base_cache_entry(ent);
1479 + base_from_cache = 1;
1480 + break;
1481 + }
1482 +
1483 + if (do_check_packed_object_crc && p->index_version > 1) {
1484 + struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
1485 + off_t len = revidx[1].offset - obj_offset;
1486 + if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) {
1487 + const unsigned char *sha1 =
1488 + nth_packed_object_sha1(p, revidx->nr);
1489 + error("bad packed object CRC for %s",
1490 + sha1_to_hex(sha1));
1491 + mark_bad_packed_object(p, sha1);
1492 + data = NULL;
1493 + goto out;
1494 + }
1495 + }
1496 +
1497 + type = unpack_object_header(p, &w_curs, &curpos, &size);
1498 + if (type != OBJ_OFS_DELTA && type != OBJ_REF_DELTA)
1499 + break;
1500 +
1501 + base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
1502 + if (!base_offset) {
1503 + error("failed to validate delta base reference "
1504 + "at offset %"PRIuMAX" from %s",
1505 + (uintmax_t)curpos, p->pack_name);
1506 + /* bail to phase 2, in hopes of recovery */
1507 + data = NULL;
1508 + break;
1509 + }
1510 +
1511 + /* push object, proceed to base */
1512 + if (delta_stack_nr >= delta_stack_alloc
1513 + && delta_stack == small_delta_stack) {
1514 + delta_stack_alloc = alloc_nr(delta_stack_nr);
1515 + ALLOC_ARRAY(delta_stack, delta_stack_alloc);
1516 + memcpy(delta_stack, small_delta_stack,
1517 + sizeof(*delta_stack)*delta_stack_nr);
1518 + } else {
1519 + ALLOC_GROW(delta_stack, delta_stack_nr+1, delta_stack_alloc);
1520 + }
1521 + i = delta_stack_nr++;
1522 + delta_stack[i].obj_offset = obj_offset;
1523 + delta_stack[i].curpos = curpos;
1524 + delta_stack[i].size = size;
1525 +
1526 + curpos = obj_offset = base_offset;
1527 + }
1528 +
1529 + /* PHASE 2: handle the base */
1530 + switch (type) {
1531 + case OBJ_OFS_DELTA:
1532 + case OBJ_REF_DELTA:
1533 + if (data)
1534 + die("BUG: unpack_entry: left loop at a valid delta");
1535 + break;
1536 + case OBJ_COMMIT:
1537 + case OBJ_TREE:
1538 + case OBJ_BLOB:
1539 + case OBJ_TAG:
1540 + if (!base_from_cache)
1541 + data = unpack_compressed_entry(p, &w_curs, curpos, size);
1542 + break;
1543 + default:
1544 + data = NULL;
1545 + error("unknown object type %i at offset %"PRIuMAX" in %s",
1546 + type, (uintmax_t)obj_offset, p->pack_name);
1547 + }
1548 +
1549 + /* PHASE 3: apply deltas in order */
1550 +
1551 + /* invariants:
1552 + * 'data' holds the base data, or NULL if there was corruption
1553 + */
1554 + while (delta_stack_nr) {
1555 + void *delta_data;
1556 + void *base = data;
1557 + void *external_base = NULL;
1558 + unsigned long delta_size, base_size = size;
1559 + int i;
1560 +
1561 + data = NULL;
1562 +
1563 + if (base)
1564 + add_delta_base_cache(p, obj_offset, base, base_size, type);
1565 +
1566 + if (!base) {
1567 + /*
1568 + * We're probably in deep shit, but let's try to fetch
1569 + * the required base anyway from another pack or loose.
1570 + * This is costly but should happen only in the presence
1571 + * of a corrupted pack, and is better than failing outright.
1572 + */
1573 + struct revindex_entry *revidx;
1574 + const unsigned char *base_sha1;
1575 + revidx = find_pack_revindex(p, obj_offset);
1576 + if (revidx) {
1577 + base_sha1 = nth_packed_object_sha1(p, revidx->nr);
1578 + error("failed to read delta base object %s"
1579 + " at offset %"PRIuMAX" from %s",
1580 + sha1_to_hex(base_sha1), (uintmax_t)obj_offset,
1581 + p->pack_name);
1582 + mark_bad_packed_object(p, base_sha1);
1583 + base = read_object(base_sha1, &type, &base_size);
1584 + external_base = base;
1585 + }
1586 + }
1587 +
1588 + i = --delta_stack_nr;
1589 + obj_offset = delta_stack[i].obj_offset;
1590 + curpos = delta_stack[i].curpos;
1591 + delta_size = delta_stack[i].size;
1592 +
1593 + if (!base)
1594 + continue;
1595 +
1596 + delta_data = unpack_compressed_entry(p, &w_curs, curpos, delta_size);
1597 +
1598 + if (!delta_data) {
1599 + error("failed to unpack compressed delta "
1600 + "at offset %"PRIuMAX" from %s",
1601 + (uintmax_t)curpos, p->pack_name);
1602 + data = NULL;
1603 + free(external_base);
1604 + continue;
1605 + }
1606 +
1607 + data = patch_delta(base, base_size,
1608 + delta_data, delta_size,
1609 + &size);
1610 +
1611 + /*
1612 + * We could not apply the delta; warn the user, but keep going.
1613 + * Our failure will be noticed either in the next iteration of
1614 + * the loop, or if this is the final delta, in the caller when
1615 + * we return NULL. Those code paths will take care of making
1616 + * a more explicit warning and retrying with another copy of
1617 + * the object.
1618 + */
1619 + if (!data)
1620 + error("failed to apply delta");
1621 +
1622 + free(delta_data);
1623 + free(external_base);
1624 + }
1625 +
1626 + if (final_type)
1627 + *final_type = type;
1628 + if (final_size)
1629 + *final_size = size;
1630 +
1631 +out:
1632 + unuse_pack(&w_curs);
1633 +
1634 + if (delta_stack != small_delta_stack)
1635 + free(delta_stack);
1636 +
1637 + return data;
1638 +}
packfile.h
+10
@@ -60,8 +60,10 @@ extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t
60 extern void close_pack_windows(struct packed_git *);
61 extern void close_all_packs(void);
62 extern void unuse_pack(struct pack_window **);
63 +extern void clear_delta_base_cache(void);
64 extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);
65
66 +extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
67 extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
68 extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
69 extern int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, unsigned long *);
@@ -70,4 +72,12 @@ extern void release_pack_memory(size_t);
72
73 extern int open_packed_git(struct packed_git *p);
74
75 +/* global flag to enable extra checks when accessing packed objects */
76 +extern int do_check_packed_object_crc;
77 +
78 +extern int packed_object_info(struct packed_git *pack, off_t offset, struct object_info *);
79 +
80 +extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);
81 +extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);
82 +
83 #endif
sha1_file.c
+14 -663
@@ -719,32 +719,6 @@ void *xmmap(void *start, size_t length,
719 return ret;
720 }
721
722 -static void mark_bad_packed_object(struct packed_git *p,
723 - const unsigned char *sha1)
724 -{
725 - unsigned i;
726 - for (i = 0; i < p->num_bad_objects; i++)
727 - if (!hashcmp(sha1, p->bad_object_sha1 + GIT_SHA1_RAWSZ * i))
728 - return;
729 - p->bad_object_sha1 = xrealloc(p->bad_object_sha1,
730 - st_mult(GIT_MAX_RAWSZ,
731 - st_add(p->num_bad_objects, 1)));
732 - hashcpy(p->bad_object_sha1 + GIT_SHA1_RAWSZ * p->num_bad_objects, sha1);
733 - p->num_bad_objects++;
734 -}
735 -
736 -static const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
737 -{
738 - struct packed_git *p;
739 - unsigned i;
740 -
741 - for (p = packed_git; p; p = p->next)
742 - for (i = 0; i < p->num_bad_objects; i++)
743 - if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
744 - return p;
745 - return NULL;
746 -}
747 -
722 /*
723 * With an in-core object data in "map", rehash it to make sure the
724 * object name actually matches "sha1" to detect object corruption.
@@ -1101,629 +1075,6 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
1075 return parse_sha1_header_extended(hdr, &oi, 0);
1076 }
1077
1104 -static off_t get_delta_base(struct packed_git *p,
1105 - struct pack_window **w_curs,
1106 - off_t *curpos,
1107 - enum object_type type,
1108 - off_t delta_obj_offset)
1109 -{
1110 - unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL);
1111 - off_t base_offset;
1112 -
1113 - /* use_pack() assured us we have [base_info, base_info + 20)
1114 - * as a range that we can look at without walking off the
1115 - * end of the mapped window. Its actually the hash size
1116 - * that is assured. An OFS_DELTA longer than the hash size
1117 - * is stupid, as then a REF_DELTA would be smaller to store.
1118 - */
1119 - if (type == OBJ_OFS_DELTA) {
1120 - unsigned used = 0;
1121 - unsigned char c = base_info[used++];
1122 - base_offset = c & 127;
1123 - while (c & 128) {
1124 - base_offset += 1;
1125 - if (!base_offset || MSB(base_offset, 7))
1126 - return 0; /* overflow */
1127 - c = base_info[used++];
1128 - base_offset = (base_offset << 7) + (c & 127);
1129 - }
1130 - base_offset = delta_obj_offset - base_offset;
1131 - if (base_offset <= 0 || base_offset >= delta_obj_offset)
1132 - return 0; /* out of bound */
1133 - *curpos += used;
1134 - } else if (type == OBJ_REF_DELTA) {
1135 - /* The base entry _must_ be in the same pack */
1136 - base_offset = find_pack_entry_one(base_info, p);
1137 - *curpos += 20;
1138 - } else
1139 - die("I am totally screwed");
1140 - return base_offset;
1141 -}
1142 -
1143 -/*
1144 - * Like get_delta_base above, but we return the sha1 instead of the pack
1145 - * offset. This means it is cheaper for REF deltas (we do not have to do
1146 - * the final object lookup), but more expensive for OFS deltas (we
1147 - * have to load the revidx to convert the offset back into a sha1).
1148 - */
1149 -static const unsigned char *get_delta_base_sha1(struct packed_git *p,
1150 - struct pack_window **w_curs,
1151 - off_t curpos,
1152 - enum object_type type,
1153 - off_t delta_obj_offset)
1154 -{
1155 - if (type == OBJ_REF_DELTA) {
1156 - unsigned char *base = use_pack(p, w_curs, curpos, NULL);
1157 - return base;
1158 - } else if (type == OBJ_OFS_DELTA) {
1159 - struct revindex_entry *revidx;
1160 - off_t base_offset = get_delta_base(p, w_curs, &curpos,
1161 - type, delta_obj_offset);
1162 -
1163 - if (!base_offset)
1164 - return NULL;
1165 -
1166 - revidx = find_pack_revindex(p, base_offset);
1167 - if (!revidx)
1168 - return NULL;
1169 -
1170 - return nth_packed_object_sha1(p, revidx->nr);
1171 - } else
1172 - return NULL;
1173 -}
1174 -
1175 -static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
1176 -{
1177 - int type;
1178 - struct revindex_entry *revidx;
1179 - const unsigned char *sha1;
1180 - revidx = find_pack_revindex(p, obj_offset);
1181 - if (!revidx)
1182 - return OBJ_BAD;
1183 - sha1 = nth_packed_object_sha1(p, revidx->nr);
1184 - mark_bad_packed_object(p, sha1);
1185 - type = sha1_object_info(sha1, NULL);
1186 - if (type <= OBJ_NONE)
1187 - return OBJ_BAD;
1188 - return type;
1189 -}
1190 -
1191 -#define POI_STACK_PREALLOC 64
1192 -
1193 -static enum object_type packed_to_object_type(struct packed_git *p,
1194 - off_t obj_offset,
1195 - enum object_type type,
1196 - struct pack_window **w_curs,
1197 - off_t curpos)
1198 -{
1199 - off_t small_poi_stack[POI_STACK_PREALLOC];
1200 - off_t *poi_stack = small_poi_stack;
1201 - int poi_stack_nr = 0, poi_stack_alloc = POI_STACK_PREALLOC;
1202 -
1203 - while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1204 - off_t base_offset;
1205 - unsigned long size;
1206 - /* Push the object we're going to leave behind */
1207 - if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) {
1208 - poi_stack_alloc = alloc_nr(poi_stack_nr);
1209 - ALLOC_ARRAY(poi_stack, poi_stack_alloc);
1210 - memcpy(poi_stack, small_poi_stack, sizeof(off_t)*poi_stack_nr);
1211 - } else {
1212 - ALLOC_GROW(poi_stack, poi_stack_nr+1, poi_stack_alloc);
1213 - }
1214 - poi_stack[poi_stack_nr++] = obj_offset;
1215 - /* If parsing the base offset fails, just unwind */
1216 - base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
1217 - if (!base_offset)
1218 - goto unwind;
1219 - curpos = obj_offset = base_offset;
1220 - type = unpack_object_header(p, w_curs, &curpos, &size);
1221 - if (type <= OBJ_NONE) {
1222 - /* If getting the base itself fails, we first
1223 - * retry the base, otherwise unwind */
1224 - type = retry_bad_packed_offset(p, base_offset);
1225 - if (type > OBJ_NONE)
1226 - goto out;
1227 - goto unwind;
1228 - }
1229 - }
1230 -
1231 - switch (type) {
1232 - case OBJ_BAD:
1233 - case OBJ_COMMIT:
1234 - case OBJ_TREE:
1235 - case OBJ_BLOB:
1236 - case OBJ_TAG:
1237 - break;
1238 - default:
1239 - error("unknown object type %i at offset %"PRIuMAX" in %s",
1240 - type, (uintmax_t)obj_offset, p->pack_name);
1241 - type = OBJ_BAD;
1242 - }
1243 -
1244 -out:
1245 - if (poi_stack != small_poi_stack)
1246 - free(poi_stack);
1247 - return type;
1248 -
1249 -unwind:
1250 - while (poi_stack_nr) {
1251 - obj_offset = poi_stack[--poi_stack_nr];
1252 - type = retry_bad_packed_offset(p, obj_offset);
1253 - if (type > OBJ_NONE)
1254 - goto out;
1255 - }
1256 - type = OBJ_BAD;
1257 - goto out;
1258 -}
1259 -
1260 -static struct hashmap delta_base_cache;
1261 -static size_t delta_base_cached;
1262 -
1263 -static LIST_HEAD(delta_base_cache_lru);
1264 -
1265 -struct delta_base_cache_key {
1266 - struct packed_git *p;
1267 - off_t base_offset;
1268 -};
1269 -
1270 -struct delta_base_cache_entry {
1271 - struct hashmap hash;
1272 - struct delta_base_cache_key key;
1273 - struct list_head lru;
1274 - void *data;
1275 - unsigned long size;
1276 - enum object_type type;
1277 -};
1278 -
1279 -static unsigned int pack_entry_hash(struct packed_git *p, off_t base_offset)
1280 -{
1281 - unsigned int hash;
1282 -
1283 - hash = (unsigned int)(intptr_t)p + (unsigned int)base_offset;
1284 - hash += (hash >> 8) + (hash >> 16);
1285 - return hash;
1286 -}
1287 -
1288 -static struct delta_base_cache_entry *
1289 -get_delta_base_cache_entry(struct packed_git *p, off_t base_offset)
1290 -{
1291 - struct hashmap_entry entry;
1292 - struct delta_base_cache_key key;
1293 -
1294 - if (!delta_base_cache.cmpfn)
1295 - return NULL;
1296 -
1297 - hashmap_entry_init(&entry, pack_entry_hash(p, base_offset));
1298 - key.p = p;
1299 - key.base_offset = base_offset;
1300 - return hashmap_get(&delta_base_cache, &entry, &key);
1301 -}
1302 -
1303 -static int delta_base_cache_key_eq(const struct delta_base_cache_key *a,
1304 - const struct delta_base_cache_key *b)
1305 -{
1306 - return a->p == b->p && a->base_offset == b->base_offset;
1307 -}
1308 -
1309 -static int delta_base_cache_hash_cmp(const void *unused_cmp_data,
1310 - const void *va, const void *vb,
1311 - const void *vkey)
1312 -{
1313 - const struct delta_base_cache_entry *a = va, *b = vb;
1314 - const struct delta_base_cache_key *key = vkey;
1315 - if (key)
1316 - return !delta_base_cache_key_eq(&a->key, key);
1317 - else
1318 - return !delta_base_cache_key_eq(&a->key, &b->key);
1319 -}
1320 -
1321 -static int in_delta_base_cache(struct packed_git *p, off_t base_offset)
1322 -{
1323 - return !!get_delta_base_cache_entry(p, base_offset);
1324 -}
1325 -
1326 -/*
1327 - * Remove the entry from the cache, but do _not_ free the associated
1328 - * entry data. The caller takes ownership of the "data" buffer, and
1329 - * should copy out any fields it wants before detaching.
1330 - */
1331 -static void detach_delta_base_cache_entry(struct delta_base_cache_entry *ent)
1332 -{
1333 - hashmap_remove(&delta_base_cache, ent, &ent->key);
1334 - list_del(&ent->lru);
1335 - delta_base_cached -= ent->size;
1336 - free(ent);
1337 -}
1338 -
1339 -static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
1340 - unsigned long *base_size, enum object_type *type)
1341 -{
1342 - struct delta_base_cache_entry *ent;
1343 -
1344 - ent = get_delta_base_cache_entry(p, base_offset);
1345 - if (!ent)
1346 - return unpack_entry(p, base_offset, type, base_size);
1347 -
1348 - if (type)
1349 - *type = ent->type;
1350 - if (base_size)
1351 - *base_size = ent->size;
1352 - return xmemdupz(ent->data, ent->size);
1353 -}
1354 -
1355 -static inline void release_delta_base_cache(struct delta_base_cache_entry *ent)
1356 -{
1357 - free(ent->data);
1358 - detach_delta_base_cache_entry(ent);
1359 -}
1360 -
1361 -void clear_delta_base_cache(void)
1362 -{
1363 - struct list_head *lru, *tmp;
1364 - list_for_each_safe(lru, tmp, &delta_base_cache_lru) {
1365 - struct delta_base_cache_entry *entry =
1366 - list_entry(lru, struct delta_base_cache_entry, lru);
1367 - release_delta_base_cache(entry);
1368 - }
1369 -}
1370 -
1371 -static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
1372 - void *base, unsigned long base_size, enum object_type type)
1373 -{
1374 - struct delta_base_cache_entry *ent = xmalloc(sizeof(*ent));
1375 - struct list_head *lru, *tmp;
1376 -
1377 - delta_base_cached += base_size;
1378 -
1379 - list_for_each_safe(lru, tmp, &delta_base_cache_lru) {
1380 - struct delta_base_cache_entry *f =
1381 - list_entry(lru, struct delta_base_cache_entry, lru);
1382 - if (delta_base_cached <= delta_base_cache_limit)
1383 - break;
1384 - release_delta_base_cache(f);
1385 - }
1386 -
1387 - ent->key.p = p;
1388 - ent->key.base_offset = base_offset;
1389 - ent->type = type;
1390 - ent->data = base;
1391 - ent->size = base_size;
1392 - list_add_tail(&ent->lru, &delta_base_cache_lru);
1393 -
1394 - if (!delta_base_cache.cmpfn)
1395 - hashmap_init(&delta_base_cache, delta_base_cache_hash_cmp, NULL, 0);
1396 - hashmap_entry_init(ent, pack_entry_hash(p, base_offset));
1397 - hashmap_add(&delta_base_cache, ent);
1398 -}
1399 -
1400 -int packed_object_info(struct packed_git *p, off_t obj_offset,
1401 - struct object_info *oi)
1402 -{
1403 - struct pack_window *w_curs = NULL;
1404 - unsigned long size;
1405 - off_t curpos = obj_offset;
1406 - enum object_type type;
1407 -
1408 - /*
1409 - * We always get the representation type, but only convert it to
1410 - * a "real" type later if the caller is interested.
1411 - */
1412 - if (oi->contentp) {
1413 - *oi->contentp = cache_or_unpack_entry(p, obj_offset, oi->sizep,
1414 - &type);
1415 - if (!*oi->contentp)
1416 - type = OBJ_BAD;
1417 - } else {
1418 - type = unpack_object_header(p, &w_curs, &curpos, &size);
1419 - }
1420 -
1421 - if (!oi->contentp && oi->sizep) {
1422 - if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1423 - off_t tmp_pos = curpos;
1424 - off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
1425 - type, obj_offset);
1426 - if (!base_offset) {
1427 - type = OBJ_BAD;
1428 - goto out;
1429 - }
1430 - *oi->sizep = get_size_from_delta(p, &w_curs, tmp_pos);
1431 - if (*oi->sizep == 0) {
1432 - type = OBJ_BAD;
1433 - goto out;
1434 - }
1435 - } else {
1436 - *oi->sizep = size;
1437 - }
1438 - }
1439 -
1440 - if (oi->disk_sizep) {
1441 - struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
1442 - *oi->disk_sizep = revidx[1].offset - obj_offset;
1443 - }
1444 -
1445 - if (oi->typep || oi->typename) {
1446 - enum object_type ptot;
1447 - ptot = packed_to_object_type(p, obj_offset, type, &w_curs,
1448 - curpos);
1449 - if (oi->typep)
1450 - *oi->typep = ptot;
1451 - if (oi->typename) {
1452 - const char *tn = typename(ptot);
1453 - if (tn)
1454 - strbuf_addstr(oi->typename, tn);
1455 - }
1456 - if (ptot < 0) {
1457 - type = OBJ_BAD;
1458 - goto out;
1459 - }
1460 - }
1461 -
1462 - if (oi->delta_base_sha1) {
1463 - if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
1464 - const unsigned char *base;
1465 -
1466 - base = get_delta_base_sha1(p, &w_curs, curpos,
1467 - type, obj_offset);
1468 - if (!base) {
1469 - type = OBJ_BAD;
1470 - goto out;
1471 - }
1472 -
1473 - hashcpy(oi->delta_base_sha1, base);
1474 - } else
1475 - hashclr(oi->delta_base_sha1);
1476 - }
1477 -
1478 - oi->whence = in_delta_base_cache(p, obj_offset) ? OI_DBCACHED :
1479 - OI_PACKED;
1480 -
1481 -out:
1482 - unuse_pack(&w_curs);
1483 - return type;
1484 -}
1485 -
1486 -static void *unpack_compressed_entry(struct packed_git *p,
1487 - struct pack_window **w_curs,
1488 - off_t curpos,
1489 - unsigned long size)
1490 -{
1491 - int st;
1492 - git_zstream stream;
1493 - unsigned char *buffer, *in;
1494 -
1495 - buffer = xmallocz_gently(size);
1496 - if (!buffer)
1497 - return NULL;
1498 - memset(&stream, 0, sizeof(stream));
1499 - stream.next_out = buffer;
1500 - stream.avail_out = size + 1;
1501 -
1502 - git_inflate_init(&stream);
1503 - do {
1504 - in = use_pack(p, w_curs, curpos, &stream.avail_in);
1505 - stream.next_in = in;
1506 - st = git_inflate(&stream, Z_FINISH);
1507 - if (!stream.avail_out)
1508 - break; /* the payload is larger than it should be */
1509 - curpos += stream.next_in - in;
1510 - } while (st == Z_OK || st == Z_BUF_ERROR);
1511 - git_inflate_end(&stream);
1512 - if ((st != Z_STREAM_END) || stream.total_out != size) {
1513 - free(buffer);
1514 - return NULL;
1515 - }
1516 -
1517 - return buffer;
1518 -}
1519 -
1520 -static void *read_object(const unsigned char *sha1, enum object_type *type,
1521 - unsigned long *size);
1522 -
1523 -static void write_pack_access_log(struct packed_git *p, off_t obj_offset)
1524 -{
1525 - static struct trace_key pack_access = TRACE_KEY_INIT(PACK_ACCESS);
1526 - trace_printf_key(&pack_access, "%s %"PRIuMAX"\n",
1527 - p->pack_name, (uintmax_t)obj_offset);
1528 -}
1529 -
1530 -int do_check_packed_object_crc;
1531 -
1532 -#define UNPACK_ENTRY_STACK_PREALLOC 64
1533 -struct unpack_entry_stack_ent {
1534 - off_t obj_offset;
1535 - off_t curpos;
1536 - unsigned long size;
1537 -};
1538 -
1539 -void *unpack_entry(struct packed_git *p, off_t obj_offset,
1540 - enum object_type *final_type, unsigned long *final_size)
1541 -{
1542 - struct pack_window *w_curs = NULL;
1543 - off_t curpos = obj_offset;
1544 - void *data = NULL;
1545 - unsigned long size;
1546 - enum object_type type;
1547 - struct unpack_entry_stack_ent small_delta_stack[UNPACK_ENTRY_STACK_PREALLOC];
1548 - struct unpack_entry_stack_ent *delta_stack = small_delta_stack;
1549 - int delta_stack_nr = 0, delta_stack_alloc = UNPACK_ENTRY_STACK_PREALLOC;
1550 - int base_from_cache = 0;
1551 -
1552 - write_pack_access_log(p, obj_offset);
1553 -
1554 - /* PHASE 1: drill down to the innermost base object */
1555 - for (;;) {
1556 - off_t base_offset;
1557 - int i;
1558 - struct delta_base_cache_entry *ent;
1559 -
1560 - ent = get_delta_base_cache_entry(p, curpos);
1561 - if (ent) {
1562 - type = ent->type;
1563 - data = ent->data;
1564 - size = ent->size;
1565 - detach_delta_base_cache_entry(ent);
1566 - base_from_cache = 1;
1567 - break;
1568 - }
1569 -
1570 - if (do_check_packed_object_crc && p->index_version > 1) {
1571 - struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
1572 - off_t len = revidx[1].offset - obj_offset;
1573 - if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) {
1574 - const unsigned char *sha1 =
1575 - nth_packed_object_sha1(p, revidx->nr);
1576 - error("bad packed object CRC for %s",
1577 - sha1_to_hex(sha1));
1578 - mark_bad_packed_object(p, sha1);
1579 - data = NULL;
1580 - goto out;
1581 - }
1582 - }
1583 -
1584 - type = unpack_object_header(p, &w_curs, &curpos, &size);
1585 - if (type != OBJ_OFS_DELTA && type != OBJ_REF_DELTA)
1586 - break;
1587 -
1588 - base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
1589 - if (!base_offset) {
1590 - error("failed to validate delta base reference "
1591 - "at offset %"PRIuMAX" from %s",
1592 - (uintmax_t)curpos, p->pack_name);
1593 - /* bail to phase 2, in hopes of recovery */
1594 - data = NULL;
1595 - break;
1596 - }
1597 -
1598 - /* push object, proceed to base */
1599 - if (delta_stack_nr >= delta_stack_alloc
1600 - && delta_stack == small_delta_stack) {
1601 - delta_stack_alloc = alloc_nr(delta_stack_nr);
1602 - ALLOC_ARRAY(delta_stack, delta_stack_alloc);
1603 - memcpy(delta_stack, small_delta_stack,
1604 - sizeof(*delta_stack)*delta_stack_nr);
1605 - } else {
1606 - ALLOC_GROW(delta_stack, delta_stack_nr+1, delta_stack_alloc);
1607 - }
1608 - i = delta_stack_nr++;
1609 - delta_stack[i].obj_offset = obj_offset;
1610 - delta_stack[i].curpos = curpos;
1611 - delta_stack[i].size = size;
1612 -
1613 - curpos = obj_offset = base_offset;
1614 - }
1615 -
1616 - /* PHASE 2: handle the base */
1617 - switch (type) {
1618 - case OBJ_OFS_DELTA:
1619 - case OBJ_REF_DELTA:
1620 - if (data)
1621 - die("BUG: unpack_entry: left loop at a valid delta");
1622 - break;
1623 - case OBJ_COMMIT:
1624 - case OBJ_TREE:
1625 - case OBJ_BLOB:
1626 - case OBJ_TAG:
1627 - if (!base_from_cache)
1628 - data = unpack_compressed_entry(p, &w_curs, curpos, size);
1629 - break;
1630 - default:
1631 - data = NULL;
1632 - error("unknown object type %i at offset %"PRIuMAX" in %s",
1633 - type, (uintmax_t)obj_offset, p->pack_name);
1634 - }
1635 -
1636 - /* PHASE 3: apply deltas in order */
1637 -
1638 - /* invariants:
1639 - * 'data' holds the base data, or NULL if there was corruption
1640 - */
1641 - while (delta_stack_nr) {
1642 - void *delta_data;
1643 - void *base = data;
1644 - void *external_base = NULL;
1645 - unsigned long delta_size, base_size = size;
1646 - int i;
1647 -
1648 - data = NULL;
1649 -
1650 - if (base)
1651 - add_delta_base_cache(p, obj_offset, base, base_size, type);
1652 -
1653 - if (!base) {
1654 - /*
1655 - * We're probably in deep shit, but let's try to fetch
1656 - * the required base anyway from another pack or loose.
1657 - * This is costly but should happen only in the presence
1658 - * of a corrupted pack, and is better than failing outright.
1659 - */
1660 - struct revindex_entry *revidx;
1661 - const unsigned char *base_sha1;
1662 - revidx = find_pack_revindex(p, obj_offset);
1663 - if (revidx) {
1664 - base_sha1 = nth_packed_object_sha1(p, revidx->nr);
1665 - error("failed to read delta base object %s"
1666 - " at offset %"PRIuMAX" from %s",
1667 - sha1_to_hex(base_sha1), (uintmax_t)obj_offset,
1668 - p->pack_name);
1669 - mark_bad_packed_object(p, base_sha1);
1670 - base = read_object(base_sha1, &type, &base_size);
1671 - external_base = base;
1672 - }
1673 - }
1674 -
1675 - i = --delta_stack_nr;
1676 - obj_offset = delta_stack[i].obj_offset;
1677 - curpos = delta_stack[i].curpos;
1678 - delta_size = delta_stack[i].size;
1679 -
1680 - if (!base)
1681 - continue;
1682 -
1683 - delta_data = unpack_compressed_entry(p, &w_curs, curpos, delta_size);
1684 -
1685 - if (!delta_data) {
1686 - error("failed to unpack compressed delta "
1687 - "at offset %"PRIuMAX" from %s",
1688 - (uintmax_t)curpos, p->pack_name);
1689 - data = NULL;
1690 - free(external_base);
1691 - continue;
1692 - }
1693 -
1694 - data = patch_delta(base, base_size,
1695 - delta_data, delta_size,
1696 - &size);
1697 -
1698 - /*
1699 - * We could not apply the delta; warn the user, but keep going.
1700 - * Our failure will be noticed either in the next iteration of
1701 - * the loop, or if this is the final delta, in the caller when
1702 - * we return NULL. Those code paths will take care of making
1703 - * a more explicit warning and retrying with another copy of
1704 - * the object.
1705 - */
1706 - if (!data)
1707 - error("failed to apply delta");
1708 -
1709 - free(delta_data);
1710 - free(external_base);
1711 - }
1712 -
1713 - if (final_type)
1714 - *final_type = type;
1715 - if (final_size)
1716 - *final_size = size;
1717 -
1718 -out:
1719 - unuse_pack(&w_curs);
1720 -
1721 - if (delta_stack != small_delta_stack)
1722 - free(delta_stack);
1723 -
1724 - return data;
1725 -}
1726 -
1078 const unsigned char *nth_packed_object_sha1(struct packed_git *p,
1079 uint32_t n)
1080 {
@@ -2083,6 +1434,20 @@ int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
1434 return type;
1435 }
1436
1437 +static void *read_object(const unsigned char *sha1, enum object_type *type,
1438 + unsigned long *size)
1439 +{
1440 + struct object_info oi = OBJECT_INFO_INIT;
1441 + void *content;
1442 + oi.typep = type;
1443 + oi.sizep = size;
1444 + oi.contentp = &content;
1445 +
1446 + if (sha1_object_info_extended(sha1, &oi, 0) < 0)
1447 + return NULL;
1448 + return content;
1449 +}
1450 +
1451 int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
1452 unsigned char *sha1)
1453 {
@@ -2101,20 +1466,6 @@ int pretend_sha1_file(void *buf, unsigned long len, enum object_type type,
1466 return 0;
1467 }
1468
2104 -static void *read_object(const unsigned char *sha1, enum object_type *type,
2105 - unsigned long *size)
2106 -{
2107 - struct object_info oi = OBJECT_INFO_INIT;
2108 - void *content;
2109 - oi.typep = type;
2110 - oi.sizep = size;
2111 - oi.contentp = &content;
2112 -
2113 - if (sha1_object_info_extended(sha1, &oi, 0) < 0)
2114 - return NULL;
2115 - return content;
2116 -}
2117 -
1469 /*
1470 * This function dies on corrupt objects; the callers who want to
1471 * deal with them should arrange to call read_object() and give error