Commit 9cc0ba6babeaa22c10600255d28d144b377b7709

Edward Thomson 2017-05-02T09:25:20

Merge pull request #4226 from libgit2/ethomson/memleak WIP: squash some memleaks

diff --git a/src/branch.c b/src/branch.c
index 7a83b83..fe4955a 100644
--- a/src/branch.c
+++ b/src/branch.c
@@ -130,14 +130,16 @@ int git_branch_create_from_annotated(
 static int branch_equals(git_repository *repo, const char *path, void *payload)
 {
 	git_reference *branch = (git_reference *) payload;
-	git_reference *head;
-	int equal;
+	git_reference *head = NULL;
+	int equal = 0;
 
 	if (git_reference__read_head(&head, repo, path) < 0 ||
-	    git_reference_type(head) != GIT_REF_SYMBOLIC)
-		return 0;
+		git_reference_type(head) != GIT_REF_SYMBOLIC)
+		goto done;
 
 	equal = !git__strcmp(head->target.symbolic, branch->name);
+
+done:
 	git_reference_free(head);
 	return equal;
 }
diff --git a/src/odb_loose.c b/src/odb_loose.c
index e14af4f..a97ac25 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -205,6 +205,11 @@ static int start_inflate(z_stream *s, git_buf *obj, void *out, size_t len)
 	return inflate(s, 0);
 }
 
+static void abort_inflate(z_stream *s)
+{
+	inflateEnd(s);
+}
+
 static int finish_inflate(z_stream *s)
 {
 	int status = Z_OK;
@@ -367,6 +372,7 @@ static int inflate_disk_obj(git_rawobj *out, git_buf *obj)
 		(used = get_object_header(&hdr, head)) == 0 ||
 		!git_object_typeisloose(hdr.type))
 	{
+		abort_inflate(&zs);
 		giterr_set(GITERR_ODB, "failed to inflate disk object");
 		return -1;
 	}
diff --git a/src/refs.c b/src/refs.c
index 31410b7..632a529 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -277,8 +277,8 @@ int git_reference__read_head(
 	}
 
 out:
-	free(name);
-	git_buf_clear(&reference);
+	git__free(name);
+	git_buf_free(&reference);
 
 	return error;
 }
diff --git a/src/remote.c b/src/remote.c
index d090fda..bd8b3cf 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -192,7 +192,7 @@ static int canonicalize_url(git_buf *out, const char *in)
 static int create_internal(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
 {
 	git_remote *remote;
-	git_config *config = NULL;
+	git_config *config_ro = NULL, *config_rw;
 	git_buf canonical_url = GIT_BUF_INIT;
 	git_buf var = GIT_BUF_INIT;
 	int error = -1;
@@ -200,7 +200,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
 	/* name is optional */
 	assert(out && repo && url);
 
-	if ((error = git_repository_config__weakptr(&config, repo)) < 0)
+	if ((error = git_repository_config_snapshot(&config_ro, repo)) < 0)
 		return error;
 
 	remote = git__calloc(1, sizeof(git_remote));
@@ -212,7 +212,8 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
 		(error = canonicalize_url(&canonical_url, url)) < 0)
 		goto on_error;
 
-	remote->url = apply_insteadof(repo->_config, canonical_url.ptr, GIT_DIRECTION_FETCH);
+	remote->url = apply_insteadof(config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH);
+	GITERR_CHECK_ALLOC(remote->url);
 
 	if (name != NULL) {
 		remote->name = git__strdup(name);
@@ -221,7 +222,8 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
 		if ((error = git_buf_printf(&var, CONFIG_URL_FMT, name)) < 0)
 			goto on_error;
 
-		if ((error = git_config_set_string(config, var.ptr, canonical_url.ptr)) < 0)
+		if ((error = git_repository_config__weakptr(&config_rw, repo)) < 0 ||
+			(error = git_config_set_string(config_rw, var.ptr, canonical_url.ptr)) < 0)
 			goto on_error;
 	}
 
@@ -233,10 +235,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
 		if (name && (error = write_add_refspec(repo, name, fetch, true)) < 0)
 			goto on_error;
 
-		if ((error = git_repository_config_snapshot(&config, repo)) < 0)
-			goto on_error;
-
-		if ((error = lookup_remote_prune_config(remote, config, name)) < 0)
+		if ((error = lookup_remote_prune_config(remote, config_ro, name)) < 0)
 			goto on_error;
 
 		/* Move the data over to where the matching functions can find them */
@@ -260,6 +259,7 @@ on_error:
 	if (error)
 		git_remote_free(remote);
 
+	git_config_free(config_ro);
 	git_buf_free(&canonical_url);
 	git_buf_free(&var);
 	return error;
diff --git a/src/repository.c b/src/repository.c
index 707b7b7..f8d19eb 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -2132,7 +2132,8 @@ int git_repository_head_for_worktree(git_reference **out, git_repository *repo, 
 out:
 	if (error)
 		git_reference_free(head);
-	git_buf_clear(&path);
+
+	git_buf_free(&path);
 
 	return error;
 }
diff --git a/src/signature.c b/src/signature.c
index e792a52..a56b8a2 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -228,8 +228,11 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
 		const char *time_start = email_end + 2;
 		const char *time_end;
 
-		if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0)
+		if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0) {
+			git__free(sig->name);
+			git__free(sig->email);
 			return signature_error("invalid Unix timestamp");
+		}
 
 		/* do we have a timezone? */
 		if (time_end + 1 < buffer_end) {
diff --git a/tests/object/lookup.c b/tests/object/lookup.c
index 277e2e0..544f32b 100644
--- a/tests/object/lookup.c
+++ b/tests/object/lookup.c
@@ -116,6 +116,7 @@ void test_object_lookup__lookup_object_with_wrong_hash_returns_error(void)
 	cl_git_pass(git_object_lookup(&object, g_repo, &oid, GIT_OBJ_COMMIT));
 	cl_git_pass(git_libgit2_opts(GIT_OPT_ENABLE_STRICT_HASH_VERIFICATION, 1));
 
+	git_object_free(object);
 	git_buf_free(&oldpath);
 	git_buf_free(&newpath);
 }