Commit 7e3ed419593a2dc9fae3bd69fdf172de015d79d9

Russell Belfer 2013-12-11T16:56:17

Fix up some valgrind leaks and warnings

diff --git a/src/diff_tform.c b/src/diff_tform.c
index 1618491..da4bdb3 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -280,11 +280,8 @@ static int normalize_find_opts(
 		git_repository_config__weakptr(&cfg, diff->repo) < 0)
 		return -1;
 
-	if (given) {
+	if (given)
 		memcpy(opts, given, sizeof(*opts));
-	} else {
-		GIT_INIT_STRUCTURE(opts, GIT_DIFF_FIND_OPTIONS_VERSION);
-	}
 
 	if (!given ||
 		 (given->flags & GIT_DIFF_FIND_ALL) == GIT_DIFF_FIND_BY_CONFIG)
@@ -815,11 +812,11 @@ int git_diff_find_similar(
 	int error = 0, result;
 	uint16_t similarity;
 	git_diff_delta *src, *tgt;
-	git_diff_find_options opts;
+	git_diff_find_options opts = GIT_DIFF_FIND_OPTIONS_INIT;
 	size_t num_deltas, num_srcs = 0, num_tgts = 0;
 	size_t tried_srcs = 0, tried_tgts = 0;
 	size_t num_rewrites = 0, num_updates = 0, num_bumped = 0;
-	void **sigcache; /* cache of similarity metric file signatures */
+	void **sigcache = NULL; /* cache of similarity metric file signatures */
 	diff_find_match *tgt2src = NULL;
 	diff_find_match *src2tgt = NULL;
 	diff_find_match *tgt2src_copy = NULL;
@@ -829,15 +826,15 @@ int git_diff_find_similar(
 	if ((error = normalize_find_opts(diff, &opts, given_opts)) < 0)
 		return error;
 
-	/* No flags set; nothing to do */
-	if ((opts.flags & GIT_DIFF_FIND_ALL) == 0)
-		return 0;
-
 	num_deltas = diff->deltas.length;
 
 	/* TODO: maybe abort if deltas.length > rename_limit ??? */
 	if (!git__is_uint32(num_deltas))
-		return 0;
+		goto cleanup;
+
+	/* No flags set; nothing to do */
+	if ((opts.flags & GIT_DIFF_FIND_ALL) == 0)
+		goto cleanup;
 
 	sigcache = git__calloc(num_deltas * 2, sizeof(void *));
 	GITERR_CHECK_ALLOC(sigcache);
@@ -1112,11 +1109,13 @@ cleanup:
 	git__free(src2tgt);
 	git__free(tgt2src_copy);
 
-	for (t = 0; t < num_deltas * 2; ++t) {
-		if (sigcache[t] != NULL)
-			opts.metric->free_signature(sigcache[t], opts.metric->payload);
+	if (sigcache) {
+		for (t = 0; t < num_deltas * 2; ++t) {
+			if (sigcache[t] != NULL)
+				opts.metric->free_signature(sigcache[t], opts.metric->payload);
+		}
+		git__free(sigcache);
 	}
-	git__free(sigcache);
 
 	if (!given_opts || !given_opts->metric)
 		git__free(opts.metric);
diff --git a/src/pack-objects.c b/src/pack-objects.c
index 7ce1b6c..335944c 100644
--- a/src/pack-objects.c
+++ b/src/pack-objects.c
@@ -332,8 +332,10 @@ static int write_object(git_buf *buf, git_packbuilder *pb, git_pobject *po)
 		git_hash_update(&pb->ctx, data, size) < 0)
 		goto on_error;
 
-	if (po->delta_data)
+	if (po->delta_data) {
 		git__free(po->delta_data);
+		po->delta_data = NULL;
+	}
 
 	git_odb_object_free(obj);
 	git_buf_free(&zbuf);
@@ -612,6 +614,15 @@ static int write_pack(git_packbuilder *pb,
 	error = cb(entry_oid.id, GIT_OID_RAWSZ, data);
 
 done:
+	/* if callback cancelled writing, we must still free delta_data */
+	for ( ; i < pb->nr_objects; ++i) {
+		po = write_order[i];
+		if (po->delta_data) {
+			git__free(po->delta_data);
+			po->delta_data = NULL;
+		}
+	}
+
 	git__free(write_order);
 	git_buf_free(&buf);
 	return error;
diff --git a/src/path.c b/src/path.c
index 365bd6c..feb2739 100644
--- a/src/path.c
+++ b/src/path.c
@@ -784,7 +784,7 @@ int git_path_iconv(git_path_iconv_t *ic, char **in, size_t *inlen)
 		return 0;
 
 	while (1) {
-		if (git_buf_grow(&ic->buf, wantlen) < 0)
+		if (git_buf_grow(&ic->buf, wantlen + 1) < 0)
 			return -1;
 
 		nfc    = ic->buf.ptr   + ic->buf.size;
diff --git a/src/submodule.c b/src/submodule.c
index 1c36d36..f6660a8 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -1148,7 +1148,7 @@ static int submodule_load_from_config(
 	 */
 
 	if (path)
-		return 0;
+		goto done;
 
 	/* copy other properties into submodule entry */
 	if (strcasecmp(property, "url") == 0) {