summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2017-12-11 16:46:05 +0000
committerEdward Thomson <ethomson@edwardthomson.com>2017-12-20 16:08:04 +0000
commitbdb542143909fc278c8ba89b0c64cdf72fcaf7d2 (patch)
tree4ffe4213c6798cced5de038d891002c17fe21c11
parenta89560d5693a2f43cc852cb5806df837dc79b790 (diff)
downloadlibgit2-bdb542143909fc278c8ba89b0c64cdf72fcaf7d2.tar.gz
hash: commoncrypto hash should support large files
Teach the CommonCrypto hash mechanisms to support large files. The hash primitives take a `CC_LONG` (aka `uint32_t`) at a time. So loop to give the hash function at most an unsigned 32 bit's worth of bytes until we have hashed the entire file.
-rw-r--r--src/hash/hash_common_crypto.h17
1 files changed, 15 insertions, 2 deletions
diff --git a/src/hash/hash_common_crypto.h b/src/hash/hash_common_crypto.h
index eeeddd0cc..4cd229d3c 100644
--- a/src/hash/hash_common_crypto.h
+++ b/src/hash/hash_common_crypto.h
@@ -16,6 +16,8 @@ struct git_hash_ctx {
CC_SHA1_CTX c;
};
+#define CC_LONG_MAX ((CC_LONG)-1)
+
#define git_hash_global_init() 0
#define git_hash_ctx_init(ctx) git_hash_init(ctx)
#define git_hash_ctx_cleanup(ctx)
@@ -27,10 +29,21 @@ GIT_INLINE(int) git_hash_init(git_hash_ctx *ctx)
return 0;
}
-GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *data, size_t len)
+GIT_INLINE(int) git_hash_update(git_hash_ctx *ctx, const void *_data, size_t len)
{
+ const unsigned char *data = _data;
+
assert(ctx);
- CC_SHA1_Update(&ctx->c, data, len);
+
+ while (len > 0) {
+ CC_LONG chunk = (len > CC_LONG_MAX) ? CC_LONG_MAX : (CC_LONG)len;
+
+ CC_SHA1_Update(&ctx->c, data, chunk);
+
+ data += chunk;
+ len -= chunk;
+ }
+
return 0;
}