]> asedeno.scripts.mit.edu Git - git.git/blobdiff - builtin-pack-objects.c
make packed_object_info() resilient to pack corruptions
[git.git] / builtin-pack-objects.c
index 59c30d1caa37416041177ff4aaf01b67f4e8add4..64aefdf23b9f66e81b8cd241a75ad5002443f96b 100644 (file)
@@ -1002,7 +1002,7 @@ static void check_object(struct object_entry *entry)
                 * We want in_pack_type even if we do not reuse delta
                 * since non-delta representations could still be reused.
                 */
-               used = unpack_object_header_gently(buf, avail,
+               used = unpack_object_header_buffer(buf, avail,
                                                   &entry->in_pack_type,
                                                   &entry->size);
 
@@ -1038,10 +1038,10 @@ static void check_object(struct object_entry *entry)
                                c = buf[used_0++];
                                ofs = (ofs << 7) + (c & 127);
                        }
-                       if (ofs >= entry->in_pack_offset)
+                       ofs = entry->in_pack_offset - ofs;
+                       if (ofs <= 0 || ofs >= entry->in_pack_offset)
                                die("delta base offset out of bound for %s",
                                    sha1_to_hex(entry->idx.sha1));
-                       ofs = entry->in_pack_offset - ofs;
                        if (reuse_delta && !entry->preferred_base) {
                                struct revindex_entry *revidx;
                                revidx = find_pack_revindex(p, ofs);
@@ -1375,7 +1375,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
        array = xcalloc(window, sizeof(struct unpacked));
 
        for (;;) {
-               struct object_entry *entry = *list++;
+               struct object_entry *entry;
                struct unpacked *n = array + idx;
                int j, max_depth, best_base = -1;
 
@@ -1384,6 +1384,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                        progress_unlock();
                        break;
                }
+               entry = *list++;
                (*list_size)--;
                if (!entry->preferred_base) {
                        (*processed)++;
@@ -1697,6 +1698,16 @@ static void prepare_pack(int window, int depth)
 
        get_object_details();
 
+       /*
+        * If we're locally repacking then we need to be doubly careful
+        * from now on in order to make sure no stealth corruption gets
+        * propagated to the new pack.  Clients receiving streamed packs
+        * should validate everything they get anyway so no need to incur
+        * the additional cost here in that case.
+        */
+       if (!pack_to_stdout)
+               do_check_packed_object_crc = 1;
+
        if (!nr_objects || !window || !depth)
                return;