diff --git a/src/filebuf.c b/src/filebuf.c index 6194fe5e3..287446673 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -108,8 +108,10 @@ void git_filebuf_cleanup(git_filebuf *file) if (file->fd_is_open && file->path_lock && git_path_exists(file->path_lock)) p_unlink(file->path_lock); - if (file->digest) - git_hash_ctx_free(file->digest); + if (file->digest) { + git_hash_ctx_cleanup(file->digest); + git__free(file->digest); + } if (file->buffer) git__free(file->buffer); @@ -221,8 +223,11 @@ int git_filebuf_open(git_filebuf *file, const char *path, int flags) /* If we are hashing on-write, allocate a new hash context */ if (flags & GIT_FILEBUF_HASH_CONTENTS) { - file->digest = git_hash_ctx_new(); + file->digest = git__calloc(1, sizeof(git_hash_ctx)); GITERR_CHECK_ALLOC(file->digest); + + if (git_hash_ctx_init(file->digest) < 0) + goto cleanup; } compression = flags >> GIT_FILEBUF_DEFLATE_SHIFT; @@ -299,7 +304,8 @@ int git_filebuf_hash(git_oid *oid, git_filebuf *file) return -1; git_hash_final(oid, file->digest); - git_hash_ctx_free(file->digest); + git_hash_ctx_cleanup(file->digest); + git__free(file->digest); file->digest = NULL; return 0; diff --git a/src/hash.c b/src/hash.c index 336030d41..21db2e129 100644 --- a/src/hash.c +++ b/src/hash.c @@ -10,38 +10,38 @@ int git_hash_buf(git_oid *out, const void *data, size_t len) { - git_hash_ctx *ctx; + git_hash_ctx ctx; int error = 0; - if ((ctx = git_hash_ctx_new()) == NULL) + if (git_hash_ctx_init(&ctx) < 0) return -1; - if ((error = git_hash_update(ctx, data, len)) >= 0) - error = git_hash_final(out, ctx); + if ((error = git_hash_update(&ctx, data, len)) >= 0) + error = git_hash_final(out, &ctx); - git_hash_ctx_free(ctx); + git_hash_ctx_cleanup(&ctx); return error; } int git_hash_vec(git_oid *out, git_buf_vec *vec, size_t n) { - git_hash_ctx *ctx; + git_hash_ctx ctx; size_t i; int error = 0; - if ((ctx = git_hash_ctx_new()) == NULL) + if (git_hash_ctx_init(&ctx) < 0) return -1; for (i = 0; i < n; i++) { - if ((error = git_hash_update(ctx, vec[i].data, vec[i].len)) < 0) + if ((error = git_hash_update(&ctx, vec[i].data, vec[i].len)) < 0) goto done; } - error = git_hash_final(out, ctx); + error = git_hash_final(out, &ctx); done: - git_hash_ctx_free(ctx); + git_hash_ctx_cleanup(&ctx); return error; } diff --git a/src/hash.h b/src/hash.h index 2a9e19837..e3f1f3f66 100644 --- a/src/hash.h +++ b/src/hash.h @@ -12,6 +12,9 @@ typedef struct git_hash_prov git_hash_prov; typedef struct git_hash_ctx git_hash_ctx; +int git_hash_ctx_init(git_hash_ctx *ctx); +void git_hash_ctx_cleanup(git_hash_ctx *ctx); + #if defined(OPENSSL_SHA1) # include "hash/hash_openssl.h" #elif defined(WIN32_SHA1) @@ -27,9 +30,6 @@ typedef struct { size_t len; } git_buf_vec; -git_hash_ctx *git_hash_ctx_new(void); -void git_hash_ctx_free(git_hash_ctx *ctx); - int git_hash_init(git_hash_ctx *c); int git_hash_update(git_hash_ctx *c, const void *data, size_t len); int git_hash_final(git_oid *out, git_hash_ctx *c); diff --git a/src/hash/hash_generic.c b/src/hash/hash_generic.c index cab5469d7..30d7a5d1e 100644 --- a/src/hash/hash_generic.c +++ b/src/hash/hash_generic.c @@ -221,18 +221,6 @@ static void hash__block(git_hash_ctx *ctx, const unsigned int *data) ctx->H[4] += E; } -git_hash_ctx *git_hash_ctx_new(void) -{ - git_hash_ctx *ctx = git__malloc(sizeof(git_hash_ctx)); - - if (!ctx) - return NULL; - - git_hash_init(ctx); - - return ctx; -} - int git_hash_init(git_hash_ctx *ctx) { ctx->size = 0; @@ -298,8 +286,3 @@ int git_hash_final(git_oid *out, git_hash_ctx *ctx) return 0; } -void git_hash_ctx_free(git_hash_ctx *ctx) -{ - if (ctx) - git__free(ctx); -} diff --git a/src/hash/hash_generic.h b/src/hash/hash_generic.h index 400c7edcc..c5891c164 100644 --- a/src/hash/hash_generic.h +++ b/src/hash/hash_generic.h @@ -16,4 +16,7 @@ struct git_hash_ctx { unsigned int W[16]; }; +#define git_hash_ctx_init(ctx) git_hash_init(ctx) +#define git_hash_ctx_cleanup(ctx) + #endif /* INCLUDE_hash_generic_h__ */ diff --git a/src/hash/hash_openssl.h b/src/hash/hash_openssl.h index b416db50c..0d37f135b 100644 --- a/src/hash/hash_openssl.h +++ b/src/hash/hash_openssl.h @@ -16,23 +16,8 @@ struct git_hash_ctx { SHA_CTX c; }; -GIT_INLINE(git_hash_ctx *) git_hash_ctx_new(void) -{ - git_hash_ctx *ctx = git__malloc(sizeof(git_hash_ctx)); - - if (!ctx) - return NULL; - - SHA1_Init(&ctx->c); - - return ctx; -} - -GIT_INLINE(void) git_hash_ctx_free(git_hash_ctx *ctx) -{ - if (ctx) - git__free(ctx); -} +#define git_hash_ctx_init(ctx) git_hash_init(ctx) +#define git_hash_ctx_cleanup(ctx) GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx) { diff --git a/src/hash/hash_ppc.c b/src/hash/hash_ppc.c index 95ad3b1a1..de89e9f5e 100644 --- a/src/hash/hash_ppc.c +++ b/src/hash/hash_ppc.c @@ -14,18 +14,6 @@ extern void hash_ppc_core(uint32_t *hash, const unsigned char *p, unsigned int nblocks); -git_hash_ctx *git_hash_ctx_new(void) -{ - git_hash_ctx *ctx = git__malloc(sizeof(git_hash_ctx)); - - if (!ctx) - return NULL; - - git_hash_init(ctx); - - return ctx; -} - int git_hash_init(git_hash_ctx *c) { c->hash[0] = 0x67452301; @@ -84,8 +72,3 @@ int git_hash_final(git_oid *oid, git_hash_ctx *c) return 0; } -void git_hash_ctx_free(git_hash_ctx *ctx) -{ - if (ctx) - git__free(ctx); -} diff --git a/src/hash/hash_ppc.h b/src/hash/hash_ppc.h index 200d19310..df78d9135 100644 --- a/src/hash/hash_ppc.h +++ b/src/hash/hash_ppc.h @@ -20,4 +20,7 @@ struct git_hash_ctx { } buf; }; +#define git_hash_ctx_init(ctx) git_hash_init(ctx) +#define git_hash_ctx_cleanup(ctx) + #endif /* INCLUDE_hash_generic_h__ */ diff --git a/src/hash/hash_win32.c b/src/hash/hash_win32.c index 26b3554b5..1fac45273 100644 --- a/src/hash/hash_win32.c +++ b/src/hash/hash_win32.c @@ -100,22 +100,12 @@ static int hash_win32_prov_init(git_hash_prov *prov) /* CryptoAPI: available in Windows XP and newer */ -GIT_INLINE(git_hash_ctx *) hash_ctx_cryptoapi_new(git_hash_prov *prov) +GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx, git_hash_prov *prov) { - git_hash_ctx *ctx; - - if ((ctx = git__calloc(1, sizeof(git_hash_ctx))) == NULL) - return NULL; - ctx->type = CRYPTOAPI; ctx->prov = prov; - if (git_hash_init(ctx) < 0) { - git__free(ctx); - return NULL; - } - - return ctx; + return git_hash_init(ctx); } GIT_INLINE(int) hash_cryptoapi_init(git_hash_ctx *ctx) @@ -158,7 +148,7 @@ GIT_INLINE(int) hash_cryptoapi_final(git_oid *out, git_hash_ctx *ctx) return error; } -GIT_INLINE(void) hash_cryptoapi_free(git_hash_ctx *ctx) +GIT_INLINE(void) hash_ctx_cryptoapi_cleanup(git_hash_ctx *ctx) { if (ctx->ctx.cryptoapi.valid) CryptDestroyHash(ctx->ctx.cryptoapi.hash_handle); @@ -166,24 +156,20 @@ GIT_INLINE(void) hash_cryptoapi_free(git_hash_ctx *ctx) /* CNG: Available in Windows Server 2008 and newer */ -GIT_INLINE(git_hash_ctx *) hash_ctx_cng_new(git_hash_prov *prov) +GIT_INLINE(int) hash_ctx_cng_init(git_hash_ctx *ctx, git_hash_prov *prov) { - git_hash_ctx *ctx; - - if ((ctx = git__calloc(1, sizeof(git_hash_ctx))) == NULL || - (ctx->ctx.cng.hash_object = git__malloc(prov->prov.cng.hash_object_size)) == NULL) - return NULL; + if ((ctx->ctx.cng.hash_object = git__malloc(prov->prov.cng.hash_object_size)) == NULL) + return -1; if (prov->prov.cng.create_hash(prov->prov.cng.handle, &ctx->ctx.cng.hash_handle, ctx->ctx.cng.hash_object, prov->prov.cng.hash_object_size, NULL, 0, 0) < 0) { git__free(ctx->ctx.cng.hash_object); - git__free(ctx); - return NULL; + return -1; } ctx->type = CNG; ctx->prov = prov; - return ctx; + return 0; } GIT_INLINE(int) hash_cng_init(git_hash_ctx *ctx) @@ -220,7 +206,7 @@ GIT_INLINE(int) hash_cng_final(git_oid *out, git_hash_ctx *ctx) return 0; } -GIT_INLINE(void) hash_cng_free(git_hash_ctx *ctx) +GIT_INLINE(void) hash_ctx_cng_cleanup(git_hash_ctx *ctx) { ctx->prov->prov.cng.destroy_hash(ctx->ctx.cng.hash_handle); git__free(ctx->ctx.cng.hash_object); @@ -228,20 +214,24 @@ GIT_INLINE(void) hash_cng_free(git_hash_ctx *ctx) /* Indirection between CryptoAPI and CNG */ -git_hash_ctx *git_hash_ctx_new() +int git_hash_ctx_init(git_hash_ctx *ctx) { git_global_st *global_state; git_hash_prov *hash_prov; + + assert(ctx); + + memset(ctx, 0x0, sizeof(git_hash_ctx)); if ((global_state = git__global_state()) == NULL) - return NULL; + return -1; hash_prov = &global_state->hash_prov; if (hash_prov->type == INVALID && hash_win32_prov_init(hash_prov) < 0) - return NULL; + return -1; - return (hash_prov->type == CNG) ? hash_ctx_cng_new(hash_prov) : hash_ctx_cryptoapi_new(hash_prov); + return (hash_prov->type == CNG) ? hash_ctx_cng_init(ctx, hash_prov) : hash_ctx_cryptoapi_init(ctx, hash_prov); } int git_hash_init(git_hash_ctx *ctx) @@ -262,15 +252,12 @@ int git_hash_final(git_oid *out, git_hash_ctx *ctx) return (ctx->type == CNG) ? hash_cng_final(out, ctx) : hash_cryptoapi_final(out, ctx); } -void git_hash_ctx_free(git_hash_ctx *ctx) +void git_hash_ctx_cleanup(git_hash_ctx *ctx) { - if (ctx == NULL) - return; + assert(ctx); if (ctx->type == CNG) - hash_cng_free(ctx); - else - hash_cryptoapi_free(ctx); - - git__free(ctx); + hash_ctx_cng_cleanup(ctx); + else if(ctx->type == CRYPTOAPI) + hash_ctx_cryptoapi_cleanup(ctx); } diff --git a/src/indexer.c b/src/indexer.c index 20337d552..4a4ed325a 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -461,10 +461,10 @@ int git_indexer_stream_finalize(git_indexer_stream *idx, git_transfer_progress * struct entry *entry; void *packfile_hash; git_oid file_hash; - git_hash_ctx *ctx; + git_hash_ctx ctx; - ctx = git_hash_ctx_new(); - GITERR_CHECK_ALLOC(ctx); + if (git_hash_ctx_init(&ctx) < 0) + return -1; /* Test for this before resolve_deltas(), as it plays with idx->off */ if (idx->off < idx->pack->mwf.size - GIT_OID_RAWSZ) { @@ -506,9 +506,9 @@ int git_indexer_stream_finalize(git_indexer_stream *idx, git_transfer_progress * /* Write out the object names (SHA-1 hashes) */ git_vector_foreach(&idx->objects, i, entry) { git_filebuf_write(&idx->index_file, &entry->oid, sizeof(git_oid)); - git_hash_update(ctx, &entry->oid, GIT_OID_RAWSZ); + git_hash_update(&ctx, &entry->oid, GIT_OID_RAWSZ); } - git_hash_final(&idx->hash, ctx); + git_hash_final(&idx->hash, &ctx); /* Write out the CRC32 values */ git_vector_foreach(&idx->objects, i, entry) { @@ -583,7 +583,7 @@ on_error: p_close(idx->pack->mwf.fd); git_filebuf_cleanup(&idx->index_file); git_buf_free(&filename); - git_hash_ctx_free(ctx); + git_hash_ctx_cleanup(&ctx); return -1; } @@ -684,10 +684,10 @@ int git_indexer_write(git_indexer *idx) struct entry *entry; void *packfile_hash; git_oid file_hash; - git_hash_ctx *ctx; + git_hash_ctx ctx; - ctx = git_hash_ctx_new(); - GITERR_CHECK_ALLOC(ctx); + if (git_hash_ctx_init(&ctx) < 0) + return -1; git_vector_sort(&idx->objects); @@ -719,11 +719,11 @@ int git_indexer_write(git_indexer *idx) /* Write out the object names (SHA-1 hashes) */ git_vector_foreach(&idx->objects, i, entry) { if ((error = git_filebuf_write(&idx->file, &entry->oid, sizeof(git_oid))) < 0 || - (error = git_hash_update(ctx, &entry->oid, GIT_OID_RAWSZ)) < 0) + (error = git_hash_update(&ctx, &entry->oid, GIT_OID_RAWSZ)) < 0) goto cleanup; } - if ((error = git_hash_final(&idx->hash, ctx)) < 0) + if ((error = git_hash_final(&idx->hash, &ctx)) < 0) goto cleanup; /* Write out the CRC32 values */ @@ -802,7 +802,7 @@ cleanup: if (error < 0) git_filebuf_cleanup(&idx->file); git_buf_free(&filename); - git_hash_ctx_free(ctx); + git_hash_ctx_cleanup(&ctx); return error; } diff --git a/src/odb.c b/src/odb.c index 027aeddaa..bc135e35c 100644 --- a/src/odb.c +++ b/src/odb.c @@ -117,7 +117,7 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type) { int hdr_len; char hdr[64], buffer[2048]; - git_hash_ctx *ctx; + git_hash_ctx ctx; ssize_t read_len = 0; int error = 0; @@ -126,16 +126,16 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type) return -1; } - ctx = git_hash_ctx_new(); - GITERR_CHECK_ALLOC(ctx); + if ((error = git_hash_ctx_init(&ctx)) < 0) + return -1; hdr_len = format_object_header(hdr, sizeof(hdr), size, type); - if ((error = git_hash_update(ctx, hdr, hdr_len)) < 0) + if ((error = git_hash_update(&ctx, hdr, hdr_len)) < 0) goto done; while (size > 0 && (read_len = p_read(fd, buffer, sizeof(buffer))) > 0) { - if ((error = git_hash_update(ctx, buffer, read_len)) < 0) + if ((error = git_hash_update(&ctx, buffer, read_len)) < 0) goto done; size -= read_len; @@ -152,10 +152,10 @@ int git_odb__hashfd(git_oid *out, git_file fd, size_t size, git_otype type) return -1; } - error = git_hash_final(out, ctx); + error = git_hash_final(out, &ctx); done: - git_hash_ctx_free(ctx); + git_hash_ctx_cleanup(&ctx); return error; } diff --git a/src/pack-objects.c b/src/pack-objects.c index 58a70d0e0..f75267629 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -103,7 +103,7 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo) *out = NULL; - pb = git__calloc(sizeof(*pb), 1); + pb = git__calloc(1, sizeof(*pb)); GITERR_CHECK_ALLOC(pb); pb->object_ix = git_oidmap_alloc(); @@ -113,9 +113,8 @@ int git_packbuilder_new(git_packbuilder **out, git_repository *repo) pb->repo = repo; pb->nr_threads = 1; /* do not spawn any thread by default */ - pb->ctx = git_hash_ctx_new(); - if (!pb->ctx || + if (git_hash_ctx_init(&pb->ctx) < 0 || git_repository_odb(&pb->odb, repo) < 0 || packbuilder_config(pb) < 0) goto on_error; @@ -297,12 +296,12 @@ static int write_object(git_buf *buf, git_packbuilder *pb, git_pobject *po) if (git_buf_put(buf, (char *)hdr, hdr_len) < 0) goto on_error; - if (git_hash_update(pb->ctx, hdr, hdr_len) < 0) + if (git_hash_update(&pb->ctx, hdr, hdr_len) < 0) goto on_error; if (type == GIT_OBJ_REF_DELTA) { if (git_buf_put(buf, (char *)po->delta->id.id, GIT_OID_RAWSZ) < 0 || - git_hash_update(pb->ctx, po->delta->id.id, GIT_OID_RAWSZ) < 0) + git_hash_update(&pb->ctx, po->delta->id.id, GIT_OID_RAWSZ) < 0) goto on_error; } @@ -319,7 +318,7 @@ static int write_object(git_buf *buf, git_packbuilder *pb, git_pobject *po) } if (git_buf_put(buf, data, size) < 0 || - git_hash_update(pb->ctx, data, size) < 0) + git_hash_update(&pb->ctx, data, size) < 0) goto on_error; if (po->delta_data) @@ -571,7 +570,7 @@ static int write_pack(git_packbuilder *pb, if (cb(&ph, sizeof(ph), data) < 0) goto on_error; - if (git_hash_update(pb->ctx, &ph, sizeof(ph)) < 0) + if (git_hash_update(&pb->ctx, &ph, sizeof(ph)) < 0) goto on_error; pb->nr_remaining = pb->nr_objects; @@ -592,7 +591,7 @@ static int write_pack(git_packbuilder *pb, git__free(write_order); git_buf_free(&buf); - if (git_hash_final(&pb->pack_oid, pb->ctx) < 0) + if (git_hash_final(&pb->pack_oid, &pb->ctx) < 0) goto on_error; return cb(pb->pack_oid.id, GIT_OID_RAWSZ, data); @@ -1319,14 +1318,13 @@ void git_packbuilder_free(git_packbuilder *pb) if (pb->odb) git_odb_free(pb->odb); - if (pb->ctx) - git_hash_ctx_free(pb->ctx); - if (pb->object_ix) git_oidmap_free(pb->object_ix); if (pb->object_list) git__free(pb->object_list); + git_hash_ctx_cleanup(&pb->ctx); + git__free(pb); } diff --git a/src/pack-objects.h b/src/pack-objects.h index 0a88f7dd7..8c01f7189 100644 --- a/src/pack-objects.h +++ b/src/pack-objects.h @@ -52,7 +52,7 @@ struct git_packbuilder { git_repository *repo; /* associated repository */ git_odb *odb; /* associated object database */ - git_hash_ctx *ctx; + git_hash_ctx ctx; uint32_t nr_objects, nr_alloc, diff --git a/src/sha1.h b/src/sha1.h deleted file mode 100644 index 41e8abad6..000000000 --- a/src/sha1.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#ifndef INCLUDE_sha1_h__ -#define INCLUDE_sha1_h__ - -#ifdef OPENSSL_SHA -# include - -#else -typedef struct { - unsigned long long size; - unsigned int H[5]; - unsigned int W[16]; -} blk_SHA_CTX; - - -void git__blk_SHA1_Init(blk_SHA_CTX *ctx); -void git__blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, size_t len); -void git__blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx); - -#define SHA_CTX blk_SHA_CTX -#define SHA1_Init git__blk_SHA1_Init -#define SHA1_Update git__blk_SHA1_Update -#define SHA1_Final git__blk_SHA1_Final - -#endif // OPENSSL_SHA - -#endif diff --git a/tests-clar/object/raw/hash.c b/tests-clar/object/raw/hash.c index 94be42cdc..f26035e45 100644 --- a/tests-clar/object/raw/hash.c +++ b/tests-clar/object/raw/hash.c @@ -23,25 +23,25 @@ static char *bye_text = "bye world\n"; void test_object_raw_hash__hash_by_blocks(void) { - git_hash_ctx *ctx; + git_hash_ctx ctx; git_oid id1, id2; - cl_assert((ctx = git_hash_ctx_new()) != NULL); + cl_git_pass(git_hash_ctx_init(&ctx)); /* should already be init'd */ - cl_git_pass(git_hash_update(ctx, hello_text, strlen(hello_text))); - cl_git_pass(git_hash_final(&id2, ctx)); + cl_git_pass(git_hash_update(&ctx, hello_text, strlen(hello_text))); + cl_git_pass(git_hash_final(&id2, &ctx)); cl_git_pass(git_oid_fromstr(&id1, hello_id)); cl_assert(git_oid_cmp(&id1, &id2) == 0); /* reinit should permit reuse */ - cl_git_pass(git_hash_init(ctx)); - cl_git_pass(git_hash_update(ctx, bye_text, strlen(bye_text))); - cl_git_pass(git_hash_final(&id2, ctx)); + cl_git_pass(git_hash_init(&ctx)); + cl_git_pass(git_hash_update(&ctx, bye_text, strlen(bye_text))); + cl_git_pass(git_hash_final(&id2, &ctx)); cl_git_pass(git_oid_fromstr(&id1, bye_id)); cl_assert(git_oid_cmp(&id1, &id2) == 0); - git_hash_ctx_free(ctx); + git_hash_ctx_cleanup(&ctx); } void test_object_raw_hash__hash_buffer_in_single_call(void)