Commit bdb542143909fc278c8ba89b0c64cdf72fcaf7d2

Edward Thomson 2017-12-11T16:46:05

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.

diff --git a/src/hash/hash_common_crypto.h b/src/hash/hash_common_crypto.h
index eeeddd0..4cd229d 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;
 }