Commit 2afb6fa46df25ef77a166b92304cc6e725103c7c

Patrick Steinhardt 2016-02-22T16:05:13

rebase: plug memory leak in `rebase_alloc` Convert `rebase_alloc` to use our usual error propagation patterns, that is accept an out-parameter and return an error code that is to be checked by the caller. This allows us to use the GITERR_CHECK_ALLOC macro, which helps static analysis.

diff --git a/src/rebase.c b/src/rebase.c
index b9d1d4f..bcad9b7 100644
--- a/src/rebase.c
+++ b/src/rebase.c
@@ -257,12 +257,12 @@ done:
 	return error;
 }
 
-static git_rebase *rebase_alloc(const git_rebase_options *rebase_opts)
+static int rebase_alloc(git_rebase **out, const git_rebase_options *rebase_opts)
 {
 	git_rebase *rebase = git__calloc(1, sizeof(git_rebase));
+	GITERR_CHECK_ALLOC(rebase);
 
-	if (!rebase)
-		return NULL;
+	*out = NULL;
 
 	if (rebase_opts)
 		memcpy(&rebase->options, rebase_opts, sizeof(git_rebase_options));
@@ -270,14 +270,16 @@ static git_rebase *rebase_alloc(const git_rebase_options *rebase_opts)
 		git_rebase_init_options(&rebase->options, GIT_REBASE_OPTIONS_VERSION);
 
 	if (rebase_opts && rebase_opts->rewrite_notes_ref) {
-		if ((rebase->options.rewrite_notes_ref = git__strdup(rebase_opts->rewrite_notes_ref)) == NULL)
-			return NULL;
+		rebase->options.rewrite_notes_ref = git__strdup(rebase_opts->rewrite_notes_ref);
+		GITERR_CHECK_ALLOC(rebase->options.rewrite_notes_ref);
 	}
 
 	if ((rebase->options.checkout_options.checkout_strategy & (GIT_CHECKOUT_SAFE | GIT_CHECKOUT_FORCE)) == 0)
 		rebase->options.checkout_options.checkout_strategy = GIT_CHECKOUT_SAFE;
 
-	return rebase;
+	*out = rebase;
+
+	return 0;
 }
 
 static int rebase_check_versions(const git_rebase_options *given_opts)
@@ -305,8 +307,8 @@ int git_rebase_open(
 	if ((error = rebase_check_versions(given_opts)) < 0)
 		return error;
 
-	rebase = rebase_alloc(given_opts);
-	GITERR_CHECK_ALLOC(rebase);
+	if (rebase_alloc(&rebase, given_opts) < 0)
+		return -1;
 
 	rebase->repo = repo;
 
@@ -708,8 +710,8 @@ int git_rebase_init(
 		branch = head_branch;
 	}
 
-	rebase = rebase_alloc(given_opts);
-	GITERR_CHECK_ALLOC(rebase);
+	if (rebase_alloc(&rebase, given_opts) < 0)
+		return -1;
 
 	rebase->repo = repo;
 	rebase->inmemory = inmemory;