]> git.ipfire.org Git - thirdparty/git.git/commitdiff
hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()`
authorPatrick Steinhardt <ps@pks.im>
Fri, 14 Jun 2024 06:49:50 +0000 (08:49 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 14 Jun 2024 17:26:32 +0000 (10:26 -0700)
Many of our hash functions have two variants, one receiving a `struct
git_hash_algo` and one that derives it via `the_repository`. Adapt all
of those functions to always require the hash algorithm as input and
drop the variants that do not accept one.

As those functions are now independent of `the_repository`, we can move
them from "hash.h" to "hash-ll.h".

Note that both in this and subsequent commits in this series we always
just pass `the_repository->hash_algo` as input even if it is obvious
that there is a repository in the context that we should be using the
hash from instead. This is done to be on the safe side and not introduce
any regressions. All callsites should eventually be amended to use a
repo passed via parameters, but this is outside the scope of this patch
series.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
17 files changed:
builtin/index-pack.c
builtin/pack-redundant.c
builtin/unpack-objects.c
commit-graph.c
csum-file.c
hash-ll.h
hash-lookup.c
hash.h
http-walker.c
match-trees.c
notes.c
pack-bitmap-write.c
pack-bitmap.c
pack-check.c
pack-write.c
packfile.c
read-cache.c

index 856428fef9577eaa7f4407d598e073e488e4d089..ea727fba165540c1ef60e3901a54101b55c8dbda 100644 (file)
@@ -1204,7 +1204,7 @@ static void parse_pack_objects(unsigned char *hash)
        the_hash_algo->init_fn(&tmp_ctx);
        the_hash_algo->clone_fn(&tmp_ctx, &input_ctx);
        the_hash_algo->final_fn(hash, &tmp_ctx);
-       if (!hasheq(fill(the_hash_algo->rawsz), hash))
+       if (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo))
                die(_("pack is corrupted (SHA1 mismatch)"));
        use(the_hash_algo->rawsz);
 
@@ -1307,11 +1307,11 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
                stop_progress_msg(&progress, msg.buf);
                strbuf_release(&msg);
                finalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0);
-               hashcpy(read_hash, pack_hash);
+               hashcpy(read_hash, pack_hash, the_repository->hash_algo);
                fixup_pack_header_footer(output_fd, pack_hash,
                                         curr_pack, nr_objects,
                                         read_hash, consumed_bytes-the_hash_algo->rawsz);
-               if (!hasheq(read_hash, tail_hash))
+               if (!hasheq(read_hash, tail_hash, the_repository->hash_algo))
                        die(_("Unexpected tail checksum for %s "
                              "(disk corruption?)"), curr_pack);
        }
index 4c735ba069caf6626791d85741f78c3869a5c89d..103c11b9d3047275fb30e4c89f5494ec03b36ffb 100644 (file)
@@ -155,7 +155,7 @@ redo_from_start:
        l = (hint == NULL) ? list->front : hint;
        prev = NULL;
        while (l) {
-               const int cmp = hashcmp(l->oid.hash, oid);
+               const int cmp = hashcmp(l->oid.hash, oid, the_repository->hash_algo);
                if (cmp > 0) /* not in list, since sorted */
                        return prev;
                if (!cmp) { /* found */
@@ -258,7 +258,8 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
        while (p1_off < p1->pack->num_objects * p1_step &&
               p2_off < p2->pack->num_objects * p2_step)
        {
-               const int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
+               const int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,
+                                       the_repository->hash_algo);
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        p1_hint = llist_sorted_remove(p1->unique_objects,
@@ -296,7 +297,8 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
        while (p1_off < p1->num_objects * p1_step &&
               p2_off < p2->num_objects * p2_step)
        {
-               int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
+               int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,
+                                 the_repository->hash_algo);
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        ret++;
index f1c85a00ae9bb6586527a845c302cba47c4c8daf..0855572c2750ff950379cc883520a19dd33afca1 100644 (file)
@@ -674,7 +674,8 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)
                if (fsck_finish(&fsck_options))
                        die(_("fsck error in pack objects"));
        }
-       if (!hasheq(fill(the_hash_algo->rawsz), oid.hash))
+       if (!hasheq(fill(the_hash_algo->rawsz), oid.hash,
+                   the_repository->hash_algo))
                die("final sha1 did not match");
        use(the_hash_algo->rawsz);
 
index e5dd3553dfe9ef273cbe7a7c29e44dba9d8afada..3429156b28d377341cf927dfeb7dedff79428bb0 100644 (file)
@@ -565,7 +565,8 @@ static int add_graph_to_chain(struct commit_graph *g,
 
                if (!cur_g ||
                    !oideq(&oids[n], &cur_g->oid) ||
-                   !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n))) {
+                   !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n),
+                           the_repository->hash_algo)) {
                        warning(_("commit-graph chain does not match"));
                        return 0;
                }
index 870748e01695f865e1e4d587cdb38f769367a5c6..f4be0804b716dbf110d4862a8ffac4d51e745762 100644 (file)
@@ -68,12 +68,12 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result,
        hashflush(f);
 
        if (f->skip_hash)
-               hashclr(f->buffer);
+               hashclr(f->buffer, the_repository->hash_algo);
        else
                the_hash_algo->final_fn(f->buffer, &f->ctx);
 
        if (result)
-               hashcpy(result, f->buffer);
+               hashcpy(result, f->buffer, the_repository->hash_algo);
        if (flags & CSUM_HASH_IN_STREAM)
                flush(f, f->buffer, the_hash_algo->rawsz);
        if (flags & CSUM_FSYNC)
@@ -237,5 +237,5 @@ int hashfile_checksum_valid(const unsigned char *data, size_t total_len)
        the_hash_algo->update_fn(&ctx, data, data_len);
        the_hash_algo->final_fn(got, &ctx);
 
-       return hasheq(got, data + data_len);
+       return hasheq(got, data + data_len, the_repository->hash_algo);
 }
index 2cfde63ae1cf029e9700185247fc833c82d54407..fabdd8ecc7635bbbd9a244d0f117a760d7e7a21d 100644 (file)
--- a/hash-ll.h
+++ b/hash-ll.h
@@ -245,7 +245,7 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
 
 const struct object_id *null_oid(void);
 
-static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
+static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
 {
        /*
         * Teach the compiler that there are only two possibilities of hash size
@@ -256,7 +256,7 @@ static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *
        return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
 }
 
-static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
+static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
 {
        /*
         * We write this here instead of deferring to hashcmp so that the
@@ -267,6 +267,17 @@ static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *s
        return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
 }
 
+static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,
+                          const struct git_hash_algo *algop)
+{
+       memcpy(sha_dst, sha_src, algop->rawsz);
+}
+
+static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)
+{
+       memset(hash, 0, algop->rawsz);
+}
+
 static inline void oidcpy(struct object_id *dst, const struct object_id *src)
 {
        memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
index 9f0f95e2b9e0c44e79bfe6ee3ec43b61e7991f4a..9aa6b82eb73a3d3e642987f644bb7fd74d88e97f 100644 (file)
@@ -112,7 +112,8 @@ int bsearch_hash(const unsigned char *hash, const uint32_t *fanout_nbo,
 
        while (lo < hi) {
                unsigned mi = lo + (hi - lo) / 2;
-               int cmp = hashcmp(table + mi * stride, hash);
+               int cmp = hashcmp(table + mi * stride, hash,
+                                 the_repository->hash_algo);
 
                if (!cmp) {
                        if (result)
diff --git a/hash.h b/hash.h
index a1161e1b22cc7ba6b5ff684c56a15a9622712f18..714938e2eb9b21160e995289cf9491aaa2c27527 100644 (file)
--- a/hash.h
+++ b/hash.h
@@ -6,11 +6,6 @@
 
 #define the_hash_algo the_repository->hash_algo
 
-static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
-{
-       return hashcmp_algop(sha1, sha2, the_hash_algo);
-}
-
 static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)
 {
        const struct git_hash_algo *algop;
@@ -18,12 +13,7 @@ static inline int oidcmp(const struct object_id *oid1, const struct object_id *o
                algop = the_hash_algo;
        else
                algop = &hash_algos[oid1->algo];
-       return hashcmp_algop(oid1->hash, oid2->hash, algop);
-}
-
-static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2)
-{
-       return hasheq_algop(sha1, sha2, the_hash_algo);
+       return hashcmp(oid1->hash, oid2->hash, algop);
 }
 
 static inline int oideq(const struct object_id *oid1, const struct object_id *oid2)
@@ -33,7 +23,7 @@ static inline int oideq(const struct object_id *oid1, const struct object_id *oi
                algop = the_hash_algo;
        else
                algop = &hash_algos[oid1->algo];
-       return hasheq_algop(oid1->hash, oid2->hash, algop);
+       return hasheq(oid1->hash, oid2->hash, algop);
 }
 
 static inline int is_null_oid(const struct object_id *oid)
@@ -41,11 +31,6 @@ static inline int is_null_oid(const struct object_id *oid)
        return oideq(oid, null_oid());
 }
 
-static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
-{
-       memcpy(sha_dst, sha_src, the_hash_algo->rawsz);
-}
-
 /* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */
 static inline void oidcpy_with_padding(struct object_id *dst,
                                       const struct object_id *src)
@@ -62,11 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,
        dst->algo = src->algo;
 }
 
-static inline void hashclr(unsigned char *hash)
-{
-       memset(hash, 0, the_hash_algo->rawsz);
-}
-
 static inline void oidclr(struct object_id *oid)
 {
        memset(oid->hash, 0, GIT_MAX_RAWSZ);
index b395ef13279eaa3f672e36512a7816fee209abf9..cf7f8c82bc7eabafa4541c104540358833d59094 100644 (file)
@@ -485,7 +485,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
 
        list_for_each(pos, head) {
                obj_req = list_entry(pos, struct object_request, node);
-               if (hasheq(obj_req->oid.hash, hash))
+               if (hasheq(obj_req->oid.hash, hash, the_repository->hash_algo))
                        break;
        }
        if (!obj_req)
index 3412b6a1401df13f25069999e7384396558fbd34..849b391d3da67f862141fdda8ab42df0901181ce 100644 (file)
@@ -237,7 +237,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
        } else {
                rewrite_with = oid2;
        }
-       hashcpy(rewrite_here, rewrite_with->hash);
+       hashcpy(rewrite_here, rewrite_with->hash, the_repository->hash_algo);
        status = write_object_file(buf, sz, OBJ_TREE, result);
        free(buf);
        return status;
diff --git a/notes.c b/notes.c
index 53ca25c814738d2ec772f9d16193e9fc2424b3b7..5296fd863fbf528b8d1ea50770cd9917c205a80e 100644 (file)
--- a/notes.c
+++ b/notes.c
@@ -149,7 +149,7 @@ static struct leaf_node *note_tree_find(struct notes_tree *t,
        void **p = note_tree_search(t, &tree, &n, key_sha1);
        if (GET_PTR_TYPE(*p) == PTR_TYPE_NOTE) {
                struct leaf_node *l = (struct leaf_node *) CLR_PTR_TYPE(*p);
-               if (hasheq(key_sha1, l->key_oid.hash))
+               if (hasheq(key_sha1, l->key_oid.hash, the_repository->hash_algo))
                        return l;
        }
        return NULL;
index 6cae670412c1e3103f480b6c6fc7c9745adcc519..59d2e3a3877b296b803812b0facb5dbfc348c7ef 100644 (file)
@@ -790,7 +790,7 @@ static void write_hash_cache(struct hashfile *f,
 void bitmap_writer_set_checksum(struct bitmap_writer *writer,
                                const unsigned char *sha1)
 {
-       hashcpy(writer->pack_checksum, sha1);
+       hashcpy(writer->pack_checksum, sha1, the_repository->hash_algo);
 }
 
 void bitmap_writer_finish(struct bitmap_writer *writer,
@@ -816,7 +816,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
        header.version = htons(default_version);
        header.options = htons(flags | options);
        header.entry_count = htonl(writer->selected_nr);
-       hashcpy(header.checksum, writer->pack_checksum);
+       hashcpy(header.checksum, writer->pack_checksum, the_repository->hash_algo);
 
        hashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz);
        dump_bitmap(f, writer->commits);
index fe8e8a51d3017f9b3cd507dea4ea3e3f33b53930..184d28f05ceb591fa109d31568dccb17899e8ad5 100644 (file)
@@ -367,7 +367,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
        if (load_bitmap_header(bitmap_git) < 0)
                goto cleanup;
 
-       if (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum)) {
+       if (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum,
+                   the_repository->hash_algo)) {
                error(_("checksum doesn't match in MIDX and bitmap"));
                goto cleanup;
        }
index 25104d5b14c1e8f9a9988f106a1ad1a6823ca31c..e7b214fcbde41fdb9e5012c135abd8209da942a9 100644 (file)
@@ -78,10 +78,11 @@ static int verify_packfile(struct repository *r,
        } while (offset < pack_sig_ofs);
        r->hash_algo->final_fn(hash, &ctx);
        pack_sig = use_pack(p, w_curs, pack_sig_ofs, NULL);
-       if (!hasheq(hash, pack_sig))
+       if (!hasheq(hash, pack_sig, the_repository->hash_algo))
                err = error("%s pack checksum mismatch",
                            p->pack_name);
-       if (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig))
+       if (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig,
+                   the_repository->hash_algo))
                err = error("%s pack checksum does not match its index",
                            p->pack_name);
        unuse_pack(w_curs);
index 80ecfa544c5d9f7980adfad829e32cabd281ecc4..eef625fa5b8f233608facabafbd27bf5a59a97d7 100644 (file)
@@ -428,7 +428,8 @@ void fixup_pack_header_footer(int pack_fd,
                if (partial_pack_offset == 0) {
                        unsigned char hash[GIT_MAX_RAWSZ];
                        the_hash_algo->final_fn(hash, &old_hash_ctx);
-                       if (!hasheq(hash, partial_pack_hash))
+                       if (!hasheq(hash, partial_pack_hash,
+                                   the_repository->hash_algo))
                                die("Unexpected checksum for %s "
                                    "(disk corruption?)", pack_name);
                        /*
index d4df7fdeea56ffe63fd1738d227b509bca2d553a..9156e9122c5c4a57f61d4f50171514577c2f110f 100644 (file)
@@ -242,7 +242,7 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
        struct packed_git *p = alloc_packed_git(alloc);
 
        memcpy(p->pack_name, path, alloc); /* includes NUL */
-       hashcpy(p->hash, sha1);
+       hashcpy(p->hash, sha1, the_repository->hash_algo);
        if (check_packed_git_idx(idx_path, p)) {
                free(p);
                return NULL;
@@ -596,7 +596,7 @@ static int open_packed_git_1(struct packed_git *p)
        if (read_result != hashsz)
                return error("packfile %s signature is unavailable", p->pack_name);
        idx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;
-       if (!hasheq(hash, idx_hash))
+       if (!hasheq(hash, idx_hash, the_repository->hash_algo))
                return error("packfile %s does not match index", p->pack_name);
        return 0;
 }
@@ -751,7 +751,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
        p->mtime = st.st_mtime;
        if (path_len < the_hash_algo->hexsz ||
            get_hash_hex(path + path_len - the_hash_algo->hexsz, p->hash))
-               hashclr(p->hash);
+               hashclr(p->hash, the_repository->hash_algo);
        return p;
 }
 
@@ -1971,7 +1971,7 @@ off_t find_pack_entry_one(const unsigned char *sha1,
                        return 0;
        }
 
-       hashcpy(oid.hash, sha1);
+       hashcpy(oid.hash, sha1, the_repository->hash_algo);
        if (bsearch_pack(&oid, p, &result))
                return nth_packed_object_offset(p, result);
        return 0;
index 10e002ce6dab3ab8d0cfaf1e2650bccd53b7ce62..2642ac955889ba63e0b2dfede94d367eb1f2dc48 100644 (file)
@@ -1735,7 +1735,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)
        the_hash_algo->init_fn(&c);
        the_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz);
        the_hash_algo->final_fn(hash, &c);
-       if (!hasheq(hash, start))
+       if (!hasheq(hash, start, the_repository->hash_algo))
                return error(_("bad index file sha1 signature"));
        return 0;
 }
@@ -2641,7 +2641,7 @@ static void copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
        ondisk->uid  = htonl(ce->ce_stat_data.sd_uid);
        ondisk->gid  = htonl(ce->ce_stat_data.sd_gid);
        ondisk->size = htonl(ce->ce_stat_data.sd_size);
-       hashcpy(ondisk->data, ce->oid.hash);
+       hashcpy(ondisk->data, ce->oid.hash, the_repository->hash_algo);
 
        flags = ce->ce_flags & ~CE_NAMEMASK;
        flags |= (ce_namelen(ce) >= CE_NAMEMASK ? CE_NAMEMASK : ce_namelen(ce));
@@ -2730,7 +2730,7 @@ static int verify_index_from(const struct index_state *istate, const char *path)
        if (n != the_hash_algo->rawsz)
                goto out;
 
-       if (!hasheq(istate->oid.hash, hash))
+       if (!hasheq(istate->oid.hash, hash, the_repository->hash_algo))
                goto out;
 
        close(fd);
@@ -3603,7 +3603,7 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size)
                src_offset += extsize;
        }
        the_hash_algo->final_fn(hash, &c);
-       if (!hasheq(hash, (const unsigned char *)index))
+       if (!hasheq(hash, (const unsigned char *)index, the_repository->hash_algo))
                return 0;
 
        /* Validate that the extension offsets returned us back to the eoie extension. */