oid->algo = GIT_HASH_SHA1;
}
+static void git_hash_sha1_discard(struct git_hash_ctx *ctx)
+{
+ git_SHA1_Discard(&ctx->state.sha1);
+}
+
static void git_hash_sha1_init_unsafe(struct git_hash_ctx *ctx)
{
ctx->algop = unsafe_hash_algo(&hash_algos[GIT_HASH_SHA1]);
oid->algo = GIT_HASH_SHA1;
}
+static void git_hash_sha1_discard_unsafe(struct git_hash_ctx *ctx)
+{
+ git_SHA1_Discard_unsafe(&ctx->state.sha1_unsafe);
+}
+
static void git_hash_sha256_init(struct git_hash_ctx *ctx)
{
ctx->algop = unsafe_hash_algo(&hash_algos[GIT_HASH_SHA256]);
oid->algo = GIT_HASH_SHA256;
}
+static void git_hash_sha256_discard(struct git_hash_ctx *ctx)
+{
+ git_SHA256_Discard(&ctx->state.sha256);
+}
+
static void git_hash_unknown_init(struct git_hash_ctx *ctx UNUSED)
{
BUG("trying to init unknown hash");
BUG("trying to finalize unknown hash");
}
+static void git_hash_unknown_discard(struct git_hash_ctx *ctx UNUSED)
+{
+ BUG("trying to discard unknown hash");
+}
+
static const struct git_hash_algo sha1_unsafe_algo = {
.name = "sha1",
.format_id = GIT_SHA1_FORMAT_ID,
.update_fn = git_hash_sha1_update_unsafe,
.final_fn = git_hash_sha1_final_unsafe,
.final_oid_fn = git_hash_sha1_final_oid_unsafe,
+ .discard_fn = git_hash_sha1_discard_unsafe,
.empty_tree = &empty_tree_oid,
.empty_blob = &empty_blob_oid,
.null_oid = &null_oid_sha1,
.update_fn = git_hash_unknown_update,
.final_fn = git_hash_unknown_final,
.final_oid_fn = git_hash_unknown_final_oid,
+ .discard_fn = git_hash_unknown_discard,
.empty_tree = NULL,
.empty_blob = NULL,
.null_oid = NULL,
.update_fn = git_hash_sha1_update,
.final_fn = git_hash_sha1_final,
.final_oid_fn = git_hash_sha1_final_oid,
+ .discard_fn = git_hash_sha1_discard,
.unsafe = &sha1_unsafe_algo,
.empty_tree = &empty_tree_oid,
.empty_blob = &empty_blob_oid,
.update_fn = git_hash_sha256_update,
.final_fn = git_hash_sha256_final,
.final_oid_fn = git_hash_sha256_final_oid,
+ .discard_fn = git_hash_sha256_discard,
.empty_tree = &empty_tree_oid_sha256,
.empty_blob = &empty_blob_oid_sha256,
.null_oid = &null_oid_sha256,
void git_hash_discard(struct git_hash_ctx *ctx)
{
- /*
- * XXX Many implementations do not need to do anything here,
- * and a dummy final() call is wasteful. But we can't fix
- * that unless our implementation API exposes a discard
- * primitive.
- */
- unsigned char dummy[GIT_MAX_RAWSZ];
- git_hash_final(dummy, ctx);
+ ctx->algop->discard_fn(ctx);
}
uint32_t hash_algo_by_name(const char *name)
# define platform_SHA1_Clone_unsafe openssl_SHA1_Clone
# define platform_SHA1_Update_unsafe openssl_SHA1_Update
# define platform_SHA1_Final_unsafe openssl_SHA1_Final
+# define platform_SHA1_Discard_unsafe openssl_SHA1_Discard
# else
# define platform_SHA_CTX_unsafe SHA_CTX
# define platform_SHA1_Init_unsafe SHA1_Init
# define platform_SHA1_Final_unsafe platform_SHA1_Final
# ifdef platform_SHA1_Clone
# define platform_SHA1_Clone_unsafe platform_SHA1_Clone
+# define platform_SHA1_Discard_unsafe platform_SHA1_Discard
# endif
# ifdef SHA1_NEEDS_CLONE_HELPER
# define SHA1_NEEDS_CLONE_HELPER_UNSAFE
#ifdef platform_SHA1_Clone
#define git_SHA1_Clone platform_SHA1_Clone
+#define git_SHA1_Discard platform_SHA1_Discard
#endif
#ifdef platform_SHA1_Clone_unsafe
# define git_SHA1_Clone_unsafe platform_SHA1_Clone_unsafe
+# define git_SHA1_Discard_unsafe platform_SHA1_Discard_unsafe
#endif
#ifndef platform_SHA256_CTX
#ifdef platform_SHA256_Clone
#define git_SHA256_Clone platform_SHA256_Clone
+#define git_SHA256_Discard platform_SHA256_Discard
#endif
#ifdef SHA1_MAX_BLOCK_SIZE
{
memcpy(dst, src, sizeof(*dst));
}
+static inline void git_SHA1_Discard(git_SHA_CTX *ctx UNUSED)
+{
+ /* noop */
+}
#endif
#ifndef SHA1_NEEDS_CLONE_HELPER_UNSAFE
static inline void git_SHA1_Clone_unsafe(git_SHA_CTX_unsafe *dst,
{
memcpy(dst, src, sizeof(*dst));
}
+static inline void git_SHA1_Discard_unsafe(git_SHA_CTX_unsafe *ctx UNUSED)
+{
+ /* noop */
+}
#endif
#ifndef SHA256_NEEDS_CLONE_HELPER
{
memcpy(dst, src, sizeof(*dst));
}
+static inline void git_SHA256_Discard(git_SHA256_CTX *ctx UNUSED)
+{
+ /* noop */
+}
#endif
/*
typedef void (*git_hash_update_fn)(struct git_hash_ctx *ctx, const void *in, size_t len);
typedef void (*git_hash_final_fn)(unsigned char *hash, struct git_hash_ctx *ctx);
typedef void (*git_hash_final_oid_fn)(struct object_id *oid, struct git_hash_ctx *ctx);
+typedef void (*git_hash_discard_fn)(struct git_hash_ctx *ctx);
struct git_hash_algo {
/*
/* The hash finalization function for object IDs. */
git_hash_final_oid_fn final_oid_fn;
+ /* Discard an initialized hash without finalizing. */
+ git_hash_discard_fn discard_fn;
+
/* The OID of the empty tree. */
const struct object_id *empty_tree;
EVP_MD_CTX_copy_ex(dst->ectx, src->ectx);
}
+static inline void openssl_SHA1_Discard(struct openssl_SHA1_CTX *ctx)
+{
+ EVP_MD_CTX_free(ctx->ectx);
+}
+
#ifndef platform_SHA_CTX
#define platform_SHA_CTX openssl_SHA1_CTX
#define platform_SHA1_Init openssl_SHA1_Init
#define platform_SHA1_Clone openssl_SHA1_Clone
#define platform_SHA1_Update openssl_SHA1_Update
#define platform_SHA1_Final openssl_SHA1_Final
+#define platform_SHA1_Discard openssl_SHA1_Discard
#endif
#endif /* SHA1_OPENSSL_H */
gcry_md_copy(dst, *src);
}
+static inline void gcrypt_SHA256_Discard(gcrypt_SHA256_CTX *ctx)
+{
+ gcry_md_close(*ctx);
+}
+
#define platform_SHA256_CTX gcrypt_SHA256_CTX
#define platform_SHA256_Init gcrypt_SHA256_Init
#define platform_SHA256_Clone gcrypt_SHA256_Clone
#define platform_SHA256_Update gcrypt_SHA256_Update
#define platform_SHA256_Final gcrypt_SHA256_Final
+#define platform_SHA256_Discard gcrypt_SHA256_Discard
#endif
EVP_MD_CTX_copy_ex(dst->ectx, src->ectx);
}
+static inline void openssl_SHA256_Discard(struct openssl_SHA256_CTX *ctx)
+{
+ EVP_MD_CTX_free(ctx->ectx);
+}
+
#define platform_SHA256_CTX openssl_SHA256_CTX
#define platform_SHA256_Init openssl_SHA256_Init
#define platform_SHA256_Clone openssl_SHA256_Clone
#define platform_SHA256_Update openssl_SHA256_Update
#define platform_SHA256_Final openssl_SHA256_Final
+#define platform_SHA256_Discard openssl_SHA256_Discard
#endif /* SHA256_OPENSSL_H */