Merge branch 'jk/verify-packfile-gently' into maint
authorJunio C Hamano <gitster@pobox.com>
Tue, 11 Oct 2016 21:21:35 +0000 (14:21 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 11 Oct 2016 21:21:36 +0000 (14:21 -0700)
A low-level function verify_packfile() was meant to show errors
that were detected without dying itself, but under some conditions
it didn't and died instead, which has been fixed.

* jk/verify-packfile-gently:
verify_packfile: check pack validity before accessing data

1  2 
pack-check.c
diff --combined pack-check.c
index d123846ea2be7c34360049864aeb3a88f505dfd1,5af987c09b108740b766d6fe9db400a53c01dd7e..c5c7763323156232748314723e39deb92b93fa4e
@@@ -57,11 -57,8 +57,8 @@@ static int verify_packfile(struct packe
        int err = 0;
        struct idx_entry *entries;
  
-       /* Note that the pack header checks are actually performed by
-        * use_pack when it first opens the pack file.  If anything
-        * goes wrong during those checks then the call will die out
-        * immediately.
-        */
+       if (!is_pack_valid(p))
+               return error("packfile %s cannot be accessed", p->pack_name);
  
        git_SHA1_Init(&ctx);
        do {
                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;
                                            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);