hash: require hash algorithm in `hasheq()`, `hashcmp()` and `hashclr()`

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>

Patrick Steinhardt committed Jun 14, 2024 at 08:49 UTC f4836570a7adbd8c70ad7a8edf6ae5a977647c06
17 files changed +52 -53
builtin/index-pack.c
+3 -3
@@ -1204,7 +1204,7 @@ static void parse_pack_objects(unsigned char *hash)
1204 the_hash_algo->init_fn(&tmp_ctx);
1205 the_hash_algo->clone_fn(&tmp_ctx, &input_ctx);
1206 the_hash_algo->final_fn(hash, &tmp_ctx);
1207 - if (!hasheq(fill(the_hash_algo->rawsz), hash))
1207 + if (!hasheq(fill(the_hash_algo->rawsz), hash, the_repository->hash_algo))
1208 die(_("pack is corrupted (SHA1 mismatch)"));
1209 use(the_hash_algo->rawsz);
1210
@@ -1307,11 +1307,11 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
1307 stop_progress_msg(&progress, msg.buf);
1308 strbuf_release(&msg);
1309 finalize_hashfile(f, tail_hash, FSYNC_COMPONENT_PACK, 0);
1310 - hashcpy(read_hash, pack_hash);
1310 + hashcpy(read_hash, pack_hash, the_repository->hash_algo);
1311 fixup_pack_header_footer(output_fd, pack_hash,
1312 curr_pack, nr_objects,
1313 read_hash, consumed_bytes-the_hash_algo->rawsz);
1314 - if (!hasheq(read_hash, tail_hash))
1314 + if (!hasheq(read_hash, tail_hash, the_repository->hash_algo))
1315 die(_("Unexpected tail checksum for %s "
1316 "(disk corruption?)"), curr_pack);
1317 }
builtin/pack-redundant.c
+5 -3
@@ -155,7 +155,7 @@ redo_from_start:
155 l = (hint == NULL) ? list->front : hint;
156 prev = NULL;
157 while (l) {
158 - const int cmp = hashcmp(l->oid.hash, oid);
158 + const int cmp = hashcmp(l->oid.hash, oid, the_repository->hash_algo);
159 if (cmp > 0) /* not in list, since sorted */
160 return prev;
161 if (!cmp) { /* found */
@@ -258,7 +258,8 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
258 while (p1_off < p1->pack->num_objects * p1_step &&
259 p2_off < p2->pack->num_objects * p2_step)
260 {
261 - const int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
261 + const int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,
262 + the_repository->hash_algo);
263 /* cmp ~ p1 - p2 */
264 if (cmp == 0) {
265 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)
297 while (p1_off < p1->num_objects * p1_step &&
298 p2_off < p2->num_objects * p2_step)
299 {
299 - int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off);
300 + int cmp = hashcmp(p1_base + p1_off, p2_base + p2_off,
301 + the_repository->hash_algo);
302 /* cmp ~ p1 - p2 */
303 if (cmp == 0) {
304 ret++;
builtin/unpack-objects.c
+2 -1
@@ -674,7 +674,8 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)
674 if (fsck_finish(&fsck_options))
675 die(_("fsck error in pack objects"));
676 }
677 - if (!hasheq(fill(the_hash_algo->rawsz), oid.hash))
677 + if (!hasheq(fill(the_hash_algo->rawsz), oid.hash,
678 + the_repository->hash_algo))
679 die("final sha1 did not match");
680 use(the_hash_algo->rawsz);
681
commit-graph.c
+2 -1
@@ -565,7 +565,8 @@ static int add_graph_to_chain(struct commit_graph *g,
565
566 if (!cur_g ||
567 !oideq(&oids[n], &cur_g->oid) ||
568 - !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n))) {
568 + !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n),
569 + the_repository->hash_algo)) {
570 warning(_("commit-graph chain does not match"));
571 return 0;
572 }
csum-file.c
+3 -3
@@ -68,12 +68,12 @@ int finalize_hashfile(struct hashfile *f, unsigned char *result,
68 hashflush(f);
69
70 if (f->skip_hash)
71 - hashclr(f->buffer);
71 + hashclr(f->buffer, the_repository->hash_algo);
72 else
73 the_hash_algo->final_fn(f->buffer, &f->ctx);
74
75 if (result)
76 - hashcpy(result, f->buffer);
76 + hashcpy(result, f->buffer, the_repository->hash_algo);
77 if (flags & CSUM_HASH_IN_STREAM)
78 flush(f, f->buffer, the_hash_algo->rawsz);
79 if (flags & CSUM_FSYNC)
@@ -237,5 +237,5 @@ int hashfile_checksum_valid(const unsigned char *data, size_t total_len)
237 the_hash_algo->update_fn(&ctx, data, data_len);
238 the_hash_algo->final_fn(got, &ctx);
239
240 - return hasheq(got, data + data_len);
240 + return hasheq(got, data + data_len, the_repository->hash_algo);
241 }
hash-ll.h
+13 -2
@@ -245,7 +245,7 @@ static inline int hash_algo_by_ptr(const struct git_hash_algo *p)
245
246 const struct object_id *null_oid(void);
247
248 -static inline int hashcmp_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
248 +static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
249 {
250 /*
251 * 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 *
256 return memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
257 }
258
259 -static inline int hasheq_algop(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
259 +static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2, const struct git_hash_algo *algop)
260 {
261 /*
262 * 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
267 return !memcmp(sha1, sha2, GIT_SHA1_RAWSZ);
268 }
269
270 +static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src,
271 + const struct git_hash_algo *algop)
272 +{
273 + memcpy(sha_dst, sha_src, algop->rawsz);
274 +}
275 +
276 +static inline void hashclr(unsigned char *hash, const struct git_hash_algo *algop)
277 +{
278 + memset(hash, 0, algop->rawsz);
279 +}
280 +
281 static inline void oidcpy(struct object_id *dst, const struct object_id *src)
282 {
283 memcpy(dst->hash, src->hash, GIT_MAX_RAWSZ);
hash-lookup.c
+2 -1
@@ -112,7 +112,8 @@ int bsearch_hash(const unsigned char *hash, const uint32_t *fanout_nbo,
112
113 while (lo < hi) {
114 unsigned mi = lo + (hi - lo) / 2;
115 - int cmp = hashcmp(table + mi * stride, hash);
115 + int cmp = hashcmp(table + mi * stride, hash,
116 + the_repository->hash_algo);
117
118 if (!cmp) {
119 if (result)
hash.h
+2 -22
@@ -6,11 +6,6 @@
6
7 #define the_hash_algo the_repository->hash_algo
8
9 -static inline int hashcmp(const unsigned char *sha1, const unsigned char *sha2)
10 -{
11 - return hashcmp_algop(sha1, sha2, the_hash_algo);
12 -}
13 -
9 static inline int oidcmp(const struct object_id *oid1, const struct object_id *oid2)
10 {
11 const struct git_hash_algo *algop;
@@ -18,12 +13,7 @@ static inline int oidcmp(const struct object_id *oid1, const struct object_id *o
13 algop = the_hash_algo;
14 else
15 algop = &hash_algos[oid1->algo];
21 - return hashcmp_algop(oid1->hash, oid2->hash, algop);
22 -}
23 -
24 -static inline int hasheq(const unsigned char *sha1, const unsigned char *sha2)
25 -{
26 - return hasheq_algop(sha1, sha2, the_hash_algo);
16 + return hashcmp(oid1->hash, oid2->hash, algop);
17 }
18
19 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
23 algop = the_hash_algo;
24 else
25 algop = &hash_algos[oid1->algo];
36 - return hasheq_algop(oid1->hash, oid2->hash, algop);
26 + return hasheq(oid1->hash, oid2->hash, algop);
27 }
28
29 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)
31 return oideq(oid, null_oid());
32 }
33
44 -static inline void hashcpy(unsigned char *sha_dst, const unsigned char *sha_src)
45 -{
46 - memcpy(sha_dst, sha_src, the_hash_algo->rawsz);
47 -}
48 -
34 /* Like oidcpy() but zero-pads the unused bytes in dst's hash array. */
35 static inline void oidcpy_with_padding(struct object_id *dst,
36 const struct object_id *src)
@@ -62,11 +47,6 @@ static inline void oidcpy_with_padding(struct object_id *dst,
47 dst->algo = src->algo;
48 }
49
65 -static inline void hashclr(unsigned char *hash)
66 -{
67 - memset(hash, 0, the_hash_algo->rawsz);
68 -}
69 -
50 static inline void oidclr(struct object_id *oid)
51 {
52 memset(oid->hash, 0, GIT_MAX_RAWSZ);
http-walker.c
+1 -1
@@ -485,7 +485,7 @@ static int fetch_object(struct walker *walker, unsigned char *hash)
485
486 list_for_each(pos, head) {
487 obj_req = list_entry(pos, struct object_request, node);
488 - if (hasheq(obj_req->oid.hash, hash))
488 + if (hasheq(obj_req->oid.hash, hash, the_repository->hash_algo))
489 break;
490 }
491 if (!obj_req)
match-trees.c
+1 -1
@@ -237,7 +237,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
237 } else {
238 rewrite_with = oid2;
239 }
240 - hashcpy(rewrite_here, rewrite_with->hash);
240 + hashcpy(rewrite_here, rewrite_with->hash, the_repository->hash_algo);
241 status = write_object_file(buf, sz, OBJ_TREE, result);
242 free(buf);
243 return status;
notes.c
+1 -1
@@ -149,7 +149,7 @@ static struct leaf_node *note_tree_find(struct notes_tree *t,
149 void **p = note_tree_search(t, &tree, &n, key_sha1);
150 if (GET_PTR_TYPE(*p) == PTR_TYPE_NOTE) {
151 struct leaf_node *l = (struct leaf_node *) CLR_PTR_TYPE(*p);
152 - if (hasheq(key_sha1, l->key_oid.hash))
152 + if (hasheq(key_sha1, l->key_oid.hash, the_repository->hash_algo))
153 return l;
154 }
155 return NULL;
pack-bitmap-write.c
+2 -2
@@ -790,7 +790,7 @@ static void write_hash_cache(struct hashfile *f,
790 void bitmap_writer_set_checksum(struct bitmap_writer *writer,
791 const unsigned char *sha1)
792 {
793 - hashcpy(writer->pack_checksum, sha1);
793 + hashcpy(writer->pack_checksum, sha1, the_repository->hash_algo);
794 }
795
796 void bitmap_writer_finish(struct bitmap_writer *writer,
@@ -816,7 +816,7 @@ void bitmap_writer_finish(struct bitmap_writer *writer,
816 header.version = htons(default_version);
817 header.options = htons(flags | options);
818 header.entry_count = htonl(writer->selected_nr);
819 - hashcpy(header.checksum, writer->pack_checksum);
819 + hashcpy(header.checksum, writer->pack_checksum, the_repository->hash_algo);
820
821 hashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + the_hash_algo->rawsz);
822 dump_bitmap(f, writer->commits);
pack-bitmap.c
+2 -1
@@ -367,7 +367,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git,
367 if (load_bitmap_header(bitmap_git) < 0)
368 goto cleanup;
369
370 - if (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum)) {
370 + if (!hasheq(get_midx_checksum(bitmap_git->midx), bitmap_git->checksum,
371 + the_repository->hash_algo)) {
372 error(_("checksum doesn't match in MIDX and bitmap"));
373 goto cleanup;
374 }
pack-check.c
+3 -2
@@ -78,10 +78,11 @@ static int verify_packfile(struct repository *r,
78 } while (offset < pack_sig_ofs);
79 r->hash_algo->final_fn(hash, &ctx);
80 pack_sig = use_pack(p, w_curs, pack_sig_ofs, NULL);
81 - if (!hasheq(hash, pack_sig))
81 + if (!hasheq(hash, pack_sig, the_repository->hash_algo))
82 err = error("%s pack checksum mismatch",
83 p->pack_name);
84 - if (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig))
84 + if (!hasheq(index_base + index_size - r->hash_algo->hexsz, pack_sig,
85 + the_repository->hash_algo))
86 err = error("%s pack checksum does not match its index",
87 p->pack_name);
88 unuse_pack(w_curs);
pack-write.c
+2 -1
@@ -428,7 +428,8 @@ void fixup_pack_header_footer(int pack_fd,
428 if (partial_pack_offset == 0) {
429 unsigned char hash[GIT_MAX_RAWSZ];
430 the_hash_algo->final_fn(hash, &old_hash_ctx);
431 - if (!hasheq(hash, partial_pack_hash))
431 + if (!hasheq(hash, partial_pack_hash,
432 + the_repository->hash_algo))
433 die("Unexpected checksum for %s "
434 "(disk corruption?)", pack_name);
435 /*
packfile.c
+4 -4
@@ -242,7 +242,7 @@ struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path)
242 struct packed_git *p = alloc_packed_git(alloc);
243
244 memcpy(p->pack_name, path, alloc); /* includes NUL */
245 - hashcpy(p->hash, sha1);
245 + hashcpy(p->hash, sha1, the_repository->hash_algo);
246 if (check_packed_git_idx(idx_path, p)) {
247 free(p);
248 return NULL;
@@ -596,7 +596,7 @@ static int open_packed_git_1(struct packed_git *p)
596 if (read_result != hashsz)
597 return error("packfile %s signature is unavailable", p->pack_name);
598 idx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;
599 - if (!hasheq(hash, idx_hash))
599 + if (!hasheq(hash, idx_hash, the_repository->hash_algo))
600 return error("packfile %s does not match index", p->pack_name);
601 return 0;
602 }
@@ -751,7 +751,7 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
751 p->mtime = st.st_mtime;
752 if (path_len < the_hash_algo->hexsz ||
753 get_hash_hex(path + path_len - the_hash_algo->hexsz, p->hash))
754 - hashclr(p->hash);
754 + hashclr(p->hash, the_repository->hash_algo);
755 return p;
756 }
757
@@ -1971,7 +1971,7 @@ off_t find_pack_entry_one(const unsigned char *sha1,
1971 return 0;
1972 }
1973
1974 - hashcpy(oid.hash, sha1);
1974 + hashcpy(oid.hash, sha1, the_repository->hash_algo);
1975 if (bsearch_pack(&oid, p, &result))
1976 return nth_packed_object_offset(p, result);
1977 return 0;
read-cache.c
+4 -4
@@ -1735,7 +1735,7 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size)
1735 the_hash_algo->init_fn(&c);
1736 the_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz);
1737 the_hash_algo->final_fn(hash, &c);
1738 - if (!hasheq(hash, start))
1738 + if (!hasheq(hash, start, the_repository->hash_algo))
1739 return error(_("bad index file sha1 signature"));
1740 return 0;
1741 }
@@ -2641,7 +2641,7 @@ static void copy_cache_entry_to_ondisk(struct ondisk_cache_entry *ondisk,
2641 ondisk->uid = htonl(ce->ce_stat_data.sd_uid);
2642 ondisk->gid = htonl(ce->ce_stat_data.sd_gid);
2643 ondisk->size = htonl(ce->ce_stat_data.sd_size);
2644 - hashcpy(ondisk->data, ce->oid.hash);
2644 + hashcpy(ondisk->data, ce->oid.hash, the_repository->hash_algo);
2645
2646 flags = ce->ce_flags & ~CE_NAMEMASK;
2647 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)
2730 if (n != the_hash_algo->rawsz)
2731 goto out;
2732
2733 - if (!hasheq(istate->oid.hash, hash))
2733 + if (!hasheq(istate->oid.hash, hash, the_repository->hash_algo))
2734 goto out;
2735
2736 close(fd);
@@ -3603,7 +3603,7 @@ static size_t read_eoie_extension(const char *mmap, size_t mmap_size)
3603 src_offset += extsize;
3604 }
3605 the_hash_algo->final_fn(hash, &c);
3606 - if (!hasheq(hash, (const unsigned char *)index))
3606 + if (!hasheq(hash, (const unsigned char *)index, the_repository->hash_algo))
3607 return 0;
3608
3609 /* Validate that the extension offsets returned us back to the eoie extension. */