| 1271 | } |
| 1272 | |
| 1273 | off_t get_delta_base(struct packed_git *p, |
| 1274 | struct pack_window **w_curs, |
| 1275 | off_t *curpos, |
| 1276 | enum object_type type, |
| 1277 | off_t delta_obj_offset) |
| 1278 | { |
| 1279 | unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL); |
| 1280 | off_t base_offset; |
| 1281 | |
| 1282 | /* use_pack() assured us we have [base_info, base_info + 20) |
| 1283 | * as a range that we can look at without walking off the |
| 1284 | * end of the mapped window. Its actually the hash size |
| 1285 | * that is assured. An OFS_DELTA longer than the hash size |
| 1286 | * is stupid, as then a REF_DELTA would be smaller to store. |
| 1287 | */ |
| 1288 | if (type == OBJ_OFS_DELTA) { |
| 1289 | unsigned used = 0; |
| 1290 | unsigned char c = base_info[used++]; |
| 1291 | base_offset = c & 127; |
| 1292 | while (c & 128) { |
| 1293 | base_offset += 1; |
| 1294 | if (!base_offset || MSB(base_offset, 7)) |
| 1295 | return 0; /* overflow */ |
| 1296 | c = base_info[used++]; |
| 1297 | base_offset = (base_offset << 7) + (c & 127); |
| 1298 | } |
| 1299 | base_offset = delta_obj_offset - base_offset; |
| 1300 | if (base_offset <= 0 || base_offset >= delta_obj_offset) |
| 1301 | return 0; /* out of bound */ |
| 1302 | *curpos += used; |
| 1303 | } else if (type == OBJ_REF_DELTA) { |
| 1304 | /* The base entry _must_ be in the same pack */ |
| 1305 | struct object_id oid; |
| 1306 | oidread(&oid, base_info, p->repo->hash_algo); |
| 1307 | base_offset = find_pack_entry_one(&oid, p); |
| 1308 | *curpos += p->repo->hash_algo->rawsz; |
| 1309 | } else |
| 1310 | die("I am totally screwed"); |
| 1311 | return base_offset; |
| 1312 | } |
| 1313 | |
| 1314 | /* |
| 1315 | * Like get_delta_base above, but we return the sha1 instead of the pack |
no test coverage detected