Skip to content

Commit 768e30e

Browse files
bk2204gitster
authored andcommitted
hash: implement and use a context cloning function
For all of our SHA-1 implementations and most of our SHA-256 implementations, the hash context we use is a real struct. For these implementations, it's possible to copy a hash context by making a copy of the struct. However, for our libgcrypt implementation, our hash context is a pointer. Consequently, copying it does not lead to an independent hash context like we intended. Fortunately, however, libgcrypt provides us with a handy function to copy hash contexts. Let's add a cloning function to the hash algorithm API, and use it in the one place we need to make a hash context copy. With this change, our libgcrypt SHA-256 implementation is fully functional with all of our other hash implementations. Signed-off-by: brian m. carlson <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2078991 commit 768e30e

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

csum-file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ void hashfile_checkpoint(struct hashfile *f, struct hashfile_checkpoint *checkpo
157157
{
158158
hashflush(f);
159159
checkpoint->offset = f->total;
160-
checkpoint->ctx = f->ctx;
160+
the_hash_algo->clone_fn(&checkpoint->ctx, &f->ctx);
161161
}
162162

163163
int hashfile_truncate(struct hashfile *f, struct hashfile_checkpoint *checkpoint)

hash.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#endif
1717

1818
#if defined(SHA256_GCRYPT)
19+
#define SHA256_NEEDS_CLONE_HELPER
1920
#include "sha256/gcrypt.h"
2021
#elif defined(SHA256_OPENSSL)
2122
#include <openssl/sha.h>
@@ -54,12 +55,28 @@
5455
#define git_SHA256_Update platform_SHA256_Update
5556
#define git_SHA256_Final platform_SHA256_Final
5657

58+
#ifdef platform_SHA256_Clone
59+
#define git_SHA256_Clone platform_SHA256_Clone
60+
#endif
61+
5762
#ifdef SHA1_MAX_BLOCK_SIZE
5863
#include "compat/sha1-chunked.h"
5964
#undef git_SHA1_Update
6065
#define git_SHA1_Update git_SHA1_Update_Chunked
6166
#endif
6267

68+
static inline void git_SHA1_Clone(git_SHA_CTX *dst, const git_SHA_CTX *src)
69+
{
70+
memcpy(dst, src, sizeof(*dst));
71+
}
72+
73+
#ifndef SHA256_NEEDS_CLONE_HELPER
74+
static inline void git_SHA256_Clone(git_SHA256_CTX *dst, const git_SHA256_CTX *src)
75+
{
76+
memcpy(dst, src, sizeof(*dst));
77+
}
78+
#endif
79+
6380
/*
6481
* Note that these constants are suitable for indexing the hash_algos array and
6582
* comparing against each other, but are otherwise arbitrary, so they should not
@@ -85,6 +102,7 @@ union git_hash_ctx {
85102
typedef union git_hash_ctx git_hash_ctx;
86103

87104
typedef void (*git_hash_init_fn)(git_hash_ctx *ctx);
105+
typedef void (*git_hash_clone_fn)(git_hash_ctx *dst, const git_hash_ctx *src);
88106
typedef void (*git_hash_update_fn)(git_hash_ctx *ctx, const void *in, size_t len);
89107
typedef void (*git_hash_final_fn)(unsigned char *hash, git_hash_ctx *ctx);
90108

@@ -110,6 +128,9 @@ struct git_hash_algo {
110128
/* The hash initialization function. */
111129
git_hash_init_fn init_fn;
112130

131+
/* The hash context cloning function. */
132+
git_hash_clone_fn clone_fn;
133+
113134
/* The hash update function. */
114135
git_hash_update_fn update_fn;
115136

sha1-file.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ static void git_hash_sha1_init(git_hash_ctx *ctx)
7474
git_SHA1_Init(&ctx->sha1);
7575
}
7676

77+
static void git_hash_sha1_clone(git_hash_ctx *dst, const git_hash_ctx *src)
78+
{
79+
git_SHA1_Clone(&dst->sha1, &src->sha1);
80+
}
81+
7782
static void git_hash_sha1_update(git_hash_ctx *ctx, const void *data, size_t len)
7883
{
7984
git_SHA1_Update(&ctx->sha1, data, len);
@@ -90,6 +95,11 @@ static void git_hash_sha256_init(git_hash_ctx *ctx)
9095
git_SHA256_Init(&ctx->sha256);
9196
}
9297

98+
static void git_hash_sha256_clone(git_hash_ctx *dst, const git_hash_ctx *src)
99+
{
100+
git_SHA256_Clone(&dst->sha256, &src->sha256);
101+
}
102+
93103
static void git_hash_sha256_update(git_hash_ctx *ctx, const void *data, size_t len)
94104
{
95105
git_SHA256_Update(&ctx->sha256, data, len);
@@ -105,6 +115,11 @@ static void git_hash_unknown_init(git_hash_ctx *ctx)
105115
BUG("trying to init unknown hash");
106116
}
107117

118+
static void git_hash_unknown_clone(git_hash_ctx *dst, const git_hash_ctx *src)
119+
{
120+
BUG("trying to clone unknown hash");
121+
}
122+
108123
static void git_hash_unknown_update(git_hash_ctx *ctx, const void *data, size_t len)
109124
{
110125
BUG("trying to update unknown hash");
@@ -123,6 +138,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
123138
0,
124139
0,
125140
git_hash_unknown_init,
141+
git_hash_unknown_clone,
126142
git_hash_unknown_update,
127143
git_hash_unknown_final,
128144
NULL,
@@ -136,6 +152,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
136152
GIT_SHA1_HEXSZ,
137153
GIT_SHA1_BLKSZ,
138154
git_hash_sha1_init,
155+
git_hash_sha1_clone,
139156
git_hash_sha1_update,
140157
git_hash_sha1_final,
141158
&empty_tree_oid,
@@ -149,6 +166,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
149166
GIT_SHA256_HEXSZ,
150167
GIT_SHA256_BLKSZ,
151168
git_hash_sha256_init,
169+
git_hash_sha256_clone,
152170
git_hash_sha256_update,
153171
git_hash_sha256_final,
154172
&empty_tree_oid_sha256,

sha256/gcrypt.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,14 @@ inline void gcrypt_SHA256_Final(unsigned char *digest, gcrypt_SHA256_CTX *ctx)
2222
memcpy(digest, gcry_md_read(*ctx, GCRY_MD_SHA256), SHA256_DIGEST_SIZE);
2323
}
2424

25+
inline void gcrypt_SHA256_Clone(gcrypt_SHA256_CTX *dst, const gcrypt_SHA256_CTX *src)
26+
{
27+
gcry_md_copy(dst, *src);
28+
}
29+
2530
#define platform_SHA256_CTX gcrypt_SHA256_CTX
2631
#define platform_SHA256_Init gcrypt_SHA256_Init
32+
#define platform_SHA256_Clone gcrypt_SHA256_Clone
2733
#define platform_SHA256_Update gcrypt_SHA256_Update
2834
#define platform_SHA256_Final gcrypt_SHA256_Final
2935

0 commit comments

Comments
 (0)