diff options
Diffstat (limited to 'pack-check.c')
-rw-r--r-- | pack-check.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/pack-check.c b/pack-check.c index 63a595c45c..d123846ea2 100644 --- a/pack-check.c +++ b/pack-check.c @@ -89,7 +89,7 @@ static int verify_packfile(struct packed_git *p, * we do not do scan-streaming check on the pack file. */ nr_objects = p->num_objects; - entries = xmalloc((nr_objects + 1) * sizeof(*entries)); + ALLOC_ARRAY(entries, nr_objects + 1); entries[nr_objects].offset = pack_sig_ofs; /* first sort entries by pack offset, since unpacking them is more efficient that way */ for (i = 0; i < nr_objects; i++) { @@ -105,6 +105,8 @@ static int verify_packfile(struct packed_git *p, void *data; enum object_type type; unsigned long size; + off_t curpos; + int data_valid; if (p->index_version > 1) { off_t offset = entries[i].offset; @@ -116,8 +118,25 @@ static int verify_packfile(struct packed_git *p, sha1_to_hex(entries[i].sha1), p->pack_name, (uintmax_t)offset); } - data = unpack_entry(p, entries[i].offset, &type, &size); - if (!data) + + curpos = entries[i].offset; + type = unpack_object_header(p, w_curs, &curpos, &size); + unuse_pack(w_curs); + + if (type == OBJ_BLOB && big_file_threshold <= size) { + /* + * Let check_sha1_signature() check it with + * the streaming interface; no point slurping + * the data in-core only to discard. + */ + data = NULL; + data_valid = 0; + } else { + data = unpack_entry(p, entries[i].offset, &type, &size); + data_valid = 1; + } + + if (data_valid && !data) err = error("cannot unpack %s from %s at offset %"PRIuMAX"", sha1_to_hex(entries[i].sha1), p->pack_name, (uintmax_t)entries[i].offset); @@ -126,7 +145,7 @@ static int verify_packfile(struct packed_git *p, sha1_to_hex(entries[i].sha1), p->pack_name); else if (fn) { int eaten = 0; - fn(entries[i].sha1, type, size, data, &eaten); + err |= fn(entries[i].sha1, type, size, data, &eaten); if (eaten) data = NULL; } |