Commit 3a197ea7ead1bc1b018eb809e92f418a00e5c3f8

lhchavez 2020-06-27T12:33:32

Make the tests pass cleanly with MemorySanitizer This change: * Initializes a few variables that were being read before being initialized. * Includes https://github.com/madler/zlib/pull/393. As such, it only works reliably with `-DUSE_BUNDLED_ZLIB=ON`.

diff --git a/deps/zlib/deflate.c b/deps/zlib/deflate.c
index 1ec7614..8d44869 100644
--- a/deps/zlib/deflate.c
+++ b/deps/zlib/deflate.c
@@ -320,6 +320,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
 
     s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
     s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    memset(s->prev, 0, s->w_size * sizeof(Pos));
     s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
 
     s->high_water = 0;      /* nothing written to s->window yet */
diff --git a/src/diff_file.c b/src/diff_file.c
index 621bff5..015e070 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -160,8 +160,10 @@ int git_diff_file_content__init_from_src(
 
 			fc->flags |= GIT_DIFF_FLAG__FREE_BLOB;
 		} else {
+			int error;
+			if ((error = git_odb_hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB)) < 0)
+				return error;
 			fc->file->size = src->buflen;
-			git_odb_hash(&fc->file->id, src->buf, src->buflen, GIT_OBJECT_BLOB);
 			fc->file->id_abbrev = GIT_OID_HEXSZ;
 
 			fc->map.len  = src->buflen;
diff --git a/src/indexer.c b/src/indexer.c
index 412dfc9..8c74f0e 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -427,7 +427,10 @@ static int store_object(git_indexer *idx)
 	pentry = git__calloc(1, sizeof(struct git_pack_entry));
 	GIT_ERROR_CHECK_ALLOC(pentry);
 
-	git_hash_final(&oid, &idx->hash_ctx);
+	if (git_hash_final(&oid, &idx->hash_ctx)) {
+		git__free(pentry);
+		goto on_error;
+	}
 	entry_size = idx->off - entry_start;
 	if (entry_start > UINT31_MAX) {
 		entry->offset = UINT32_MAX;
diff --git a/src/object.c b/src/object.c
index 1b47ab1..749b0ca 100644
--- a/src/object.c
+++ b/src/object.c
@@ -86,7 +86,8 @@ int git_object__from_raw(
 	GIT_ERROR_CHECK_ALLOC(object);
 	object->cached.flags = GIT_CACHE_STORE_PARSED;
 	object->cached.type = type;
-	git_odb_hash(&object->cached.oid, data, size, type);
+	if ((error = git_odb_hash(&object->cached.oid, data, size, type)) < 0)
+		return error;
 
 	/* Parse raw object data */
 	def = &git_objects_table[type];
diff --git a/src/odb.c b/src/odb.c
index 90565b7..9d95302 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -1283,12 +1283,13 @@ int git_odb_write(
 	git_oid *oid, git_odb *db, const void *data, size_t len, git_object_t type)
 {
 	size_t i;
-	int error = GIT_ERROR;
+	int error;
 	git_odb_stream *stream;
 
 	assert(oid && db);
 
-	git_odb_hash(oid, data, len, type);
+	if ((error = git_odb_hash(oid, data, len, type)) < 0)
+		return error;
 
 	if (git_oid_is_zero(oid))
 		return error_null_oid(GIT_EINVALID, "cannot write object");
@@ -1296,7 +1297,7 @@ int git_odb_write(
 	if (git_odb__freshen(db, oid))
 		return 0;
 
-	for (i = 0; i < db->backends.length && error < 0; ++i) {
+	for (i = 0, error = GIT_ERROR; i < db->backends.length && error < 0; ++i) {
 		backend_internal *internal = git_vector_get(&db->backends, i);
 		git_odb_backend *b = internal->backend;
 
diff --git a/src/odb_loose.c b/src/odb_loose.c
index 4a54b3f..6828779 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -304,7 +304,7 @@ static int read_loose_standard(git_rawobj *out, git_buf *obj)
 	 * (including the initial sequence in the head buffer).
 	 */
 	if (GIT_ADD_SIZET_OVERFLOW(&alloc_size, hdr.size, 1) ||
-		(body = git__malloc(alloc_size)) == NULL) {
+		(body = git__calloc(1, alloc_size)) == NULL) {
 		error = -1;
 		goto done;
 	}
@@ -386,8 +386,8 @@ static int read_header_loose_standard(
 	git_rawobj *out, const unsigned char *data, size_t len)
 {
 	git_zstream zs = GIT_ZSTREAM_INIT;
-	obj_hdr hdr;
-	unsigned char inflated[MAX_HEADER_LEN];
+	obj_hdr hdr = {0};
+	unsigned char inflated[MAX_HEADER_LEN] = {0};
 	size_t header_len, inflated_len = sizeof(inflated);
 	int error;
 
diff --git a/src/regexp.c b/src/regexp.c
index 5fe49f3..c1b9ef4 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -12,7 +12,7 @@
 int git_regexp_compile(git_regexp *r, const char *pattern, int flags)
 {
 	int erroffset, cflags = 0;
-	const char *error;
+	const char *error = NULL;
 
 	if (flags & GIT_REGEXP_ICASE)
 		cflags |= PCRE_CASELESS;
@@ -41,7 +41,7 @@ int git_regexp_match(const git_regexp *r, const char *string)
 
 int git_regexp_search(const git_regexp *r, const char *string, size_t nmatches, git_regmatch *matches)
 {
-	int static_ovec[9], *ovec;
+	int static_ovec[9] = {0}, *ovec;
 	int error;
 	size_t i;
 
diff --git a/tests/checkout/tree.c b/tests/checkout/tree.c
index 380d251..f8d9abe 100644
--- a/tests/checkout/tree.c
+++ b/tests/checkout/tree.c
@@ -917,7 +917,7 @@ void test_checkout_tree__extremely_long_file_name(void)
 {
 	/* A utf-8 string with 83 characters, but 249 bytes. */
 	const char *longname = "\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97\xe5\x8f\x97";
-	char path[1024];
+	char path[1024] = {0};
 
 	g_opts.checkout_strategy = GIT_CHECKOUT_FORCE;
 	cl_git_pass(git_revparse_single(&g_object, g_repo, "long-file-name"));
diff --git a/tests/status/worktree.c b/tests/status/worktree.c
index 7711b2d..d284248 100644
--- a/tests/status/worktree.c
+++ b/tests/status/worktree.c
@@ -949,7 +949,7 @@ void test_status_worktree__sorting_by_case(void)
 
 void test_status_worktree__long_filenames(void)
 {
-	char path[260*4+1];
+	char path[260*4+1] = {0};
 	const char *expected_paths[] = {path};
 	const unsigned int expected_statuses[] = {GIT_STATUS_WT_NEW};