]> git.ipfire.org Git - thirdparty/git.git/blobdiff - packfile.c
unpack_entry(): convert to new revindex API
[thirdparty/git.git] / packfile.c
index 0929ebe4fc747fc52c98d45542d9b257dc25a31d..936ab3def53a3af1a0f42944874de483ef8f6601 100644 (file)
@@ -148,7 +148,7 @@ int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
                 *  - hash of the packfile
                 *  - file checksum
                 */
-               if (idx_size != 4 * 256 + nr * (hashsz + 4) + hashsz + hashsz)
+               if (idx_size != st_add(4 * 256 + hashsz + hashsz, st_mult(nr, hashsz + 4)))
                        return error("wrong index v1 file size in %s", path);
        } else if (version == 2) {
                /*
@@ -164,10 +164,10 @@ int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
                 * variable sized table containing 8-byte entries
                 * for offsets larger than 2^31.
                 */
-               unsigned long min_size = 8 + 4*256 + nr*(hashsz + 4 + 4) + hashsz + hashsz;
-               unsigned long max_size = min_size;
+               size_t min_size = st_add(8 + 4*256 + hashsz + hashsz, st_mult(nr, hashsz + 4 + 4));
+               size_t max_size = min_size;
                if (nr)
-                       max_size += (nr - 1)*8;
+                       max_size = st_add(max_size, st_mult(nr - 1, 8));
                if (idx_size < min_size || idx_size > max_size)
                        return error("wrong index v2 file size in %s", path);
                if (idx_size != min_size &&
@@ -514,19 +514,8 @@ static int open_packed_git_1(struct packed_git *p)
        ssize_t read_result;
        const unsigned hashsz = the_hash_algo->rawsz;
 
-       if (!p->index_data) {
-               struct multi_pack_index *m;
-               const char *pack_name = pack_basename(p);
-
-               for (m = the_repository->objects->multi_pack_index;
-                    m; m = m->next) {
-                       if (midx_contains_pack(m, pack_name))
-                               break;
-               }
-
-               if (!m && open_pack_index(p))
-                       return error("packfile %s index unavailable", p->pack_name);
-       }
+       if (open_pack_index(p))
+               return error("packfile %s index unavailable", p->pack_name);
 
        if (!pack_max_fds) {
                unsigned int max_fds = get_max_fd_limit();
@@ -567,10 +556,6 @@ static int open_packed_git_1(struct packed_git *p)
                        " supported (try upgrading GIT to a newer version)",
                        p->pack_name, ntohl(hdr.hdr_version));
 
-       /* Skip index checking if in multi-pack-index */
-       if (!p->index_data)
-               return 0;
-
        /* Verify the pack matches its index. */
        if (p->num_objects != ntohl(hdr.hdr_entries))
                return error("packfile %s claims to have %"PRIu32" objects"
@@ -1250,18 +1235,18 @@ static int get_delta_base_oid(struct packed_git *p,
                oidread(oid, base);
                return 0;
        } else if (type == OBJ_OFS_DELTA) {
-               struct revindex_entry *revidx;
+               uint32_t base_pos;
                off_t base_offset = get_delta_base(p, w_curs, &curpos,
                                                   type, delta_obj_offset);
 
                if (!base_offset)
                        return -1;
 
-               revidx = find_pack_revindex(p, base_offset);
-               if (!revidx)
+               if (offset_to_pack_pos(p, base_offset, &base_pos) < 0)
                        return -1;
 
-               return nth_packed_object_id(oid, p, revidx->nr);
+               return nth_packed_object_id(oid, p,
+                                           pack_pos_to_index(p, base_pos));
        } else
                return -1;
 }
@@ -1271,12 +1256,11 @@ static int retry_bad_packed_offset(struct repository *r,
                                   off_t obj_offset)
 {
        int type;
-       struct revindex_entry *revidx;
+       uint32_t pos;
        struct object_id oid;
-       revidx = find_pack_revindex(p, obj_offset);
-       if (!revidx)
+       if (offset_to_pack_pos(p, obj_offset, &pos) < 0)
                return OBJ_BAD;
-       nth_packed_object_id(&oid, p, revidx->nr);
+       nth_packed_object_id(&oid, p, pack_pos_to_index(p, pos));
        mark_bad_packed_object(p, oid.hash);
        type = oid_object_info(r, &oid, NULL);
        if (type <= OBJ_NONE)
@@ -1553,8 +1537,15 @@ int packed_object_info(struct repository *r, struct packed_git *p,
        }
 
        if (oi->disk_sizep) {
-               struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
-               *oi->disk_sizep = revidx[1].offset - obj_offset;
+               uint32_t pos;
+               if (offset_to_pack_pos(p, obj_offset, &pos) < 0) {
+                       error("could not find object at offset %"PRIuMAX" "
+                             "in pack %s", (uintmax_t)obj_offset, p->pack_name);
+                       type = OBJ_BAD;
+                       goto out;
+               }
+
+               *oi->disk_sizep = pack_pos_to_offset(p, pos + 1) - obj_offset;
        }
 
        if (oi->typep || oi->type_name) {
@@ -1703,11 +1694,21 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
                }
 
                if (do_check_packed_object_crc && p->index_version > 1) {
-                       struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
-                       off_t len = revidx[1].offset - obj_offset;
-                       if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) {
+                       uint32_t pack_pos, index_pos;
+                       off_t len;
+
+                       if (offset_to_pack_pos(p, obj_offset, &pack_pos) < 0) {
+                               error("could not find object at offset %"PRIuMAX" in pack %s",
+                                     (uintmax_t)obj_offset, p->pack_name);
+                               data = NULL;
+                               goto out;
+                       }
+
+                       len = pack_pos_to_offset(p, pack_pos + 1) - obj_offset;
+                       index_pos = pack_pos_to_index(p, pack_pos);
+                       if (check_pack_crc(p, &w_curs, obj_offset, len, index_pos)) {
                                struct object_id oid;
-                               nth_packed_object_id(&oid, p, revidx->nr);
+                               nth_packed_object_id(&oid, p, index_pos);
                                error("bad packed object CRC for %s",
                                      oid_to_hex(&oid));
                                mark_bad_packed_object(p, oid.hash);
@@ -1790,11 +1791,11 @@ void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
                         * This is costly but should happen only in the presence
                         * of a corrupted pack, and is better than failing outright.
                         */
-                       struct revindex_entry *revidx;
+                       uint32_t pos;
                        struct object_id base_oid;
-                       revidx = find_pack_revindex(p, obj_offset);
-                       if (revidx) {
-                               nth_packed_object_id(&base_oid, p, revidx->nr);
+                       if (!(offset_to_pack_pos(p, obj_offset, &pos))) {
+                               nth_packed_object_id(&base_oid, p,
+                                                    pack_pos_to_index(p, pos));
                                error("failed to read delta base object %s"
                                      " at offset %"PRIuMAX" from %s",
                                      oid_to_hex(&base_oid), (uintmax_t)obj_offset,
@@ -1933,14 +1934,14 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
        const unsigned int hashsz = the_hash_algo->rawsz;
        index += 4 * 256;
        if (p->index_version == 1) {
-               return ntohl(*((uint32_t *)(index + (hashsz + 4) * n)));
+               return ntohl(*((uint32_t *)(index + (hashsz + 4) * (size_t)n)));
        } else {
                uint32_t off;
-               index += 8 + p->num_objects * (hashsz + 4);
+               index += 8 + (size_t)p->num_objects * (hashsz + 4);
                off = ntohl(*((uint32_t *)(index + 4 * n)));
                if (!(off & 0x80000000))
                        return off;
-               index += p->num_objects * 4 + (off & 0x7fffffff) * 8;
+               index += (size_t)p->num_objects * 4 + (off & 0x7fffffff) * 8;
                check_pack_index_ptr(p, index);
                return get_be64(index);
        }