git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jared Hance <jaredhance@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, Jared Hance <jaredhance@gmail.com>
Subject: [PATCH v2 2/3] Fix memory leak in apply_patch in apply.c.
Date: Sat,  3 Mar 2012 09:40:29 -0500	[thread overview]
Message-ID: <e631bb2059c800f9d49eed51cfa5ba4d04106a2e.1330785363.git.jaredhance@gmail.com> (raw)
In-Reply-To: <cover.1330740964.git.jaredhance@gmail.com>
In-Reply-To: <cover.1330785363.git.jaredhance@gmail.com>

In the while loop inside apply_patch, patch is dynamically allocated
with a calloc. However, only unused patches are actually free'd; the
rest are left in a memory leak. Since a list is actively built up
consisting of the used patches, they can simply be iterated and free'd
at the end of the function.

In addition, the list of fragments should be free'd. To fix this, the
utility function free_patch has been implemented. It loops over the
entire patch list, and in each patch, loops over the fragment list,
freeing the fragments, followed by the patch in the list. It frees both
patch and patch->next.

The main caveat is that the text in a fragment, ie,
patch->fragments->patch, may or may not need to be free'd. The text is
dynamically allocated and needs to be freed iff the patch is a binary
patch, as allocation occurs in inflate_it.

Signed-off-by: Jared Hance <jaredhance@gmail.com>
---
 builtin/apply.c |   30 +++++++++++++++++++++++++++---
 1 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/builtin/apply.c b/builtin/apply.c
index 389898f..a73d339 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -196,6 +196,30 @@ struct patch {
 	struct patch *next;
 };
 
+static void free_patch(struct patch *patch) {
+    while(patch != NULL) {
+	struct patch *patch_next;
+	struct fragment *fragment;
+
+	patch_next = patch->next;
+
+	fragment = patch->fragments;
+	while(fragment != NULL) {
+	    struct fragment *fragment_next = fragment->next;
+	    if(fragment->patch != NULL) {
+		if(patch->is_binary) {
+		    free((void*) fragment->patch);
+		}
+	    }
+	    free(fragment);
+	    fragment = fragment_next;
+	}
+
+	free(patch);
+	patch = patch_next;
+    }
+}
+
 /*
  * A line in a file, len-bytes long (includes the terminating LF,
  * except for an incomplete line at the end if the file ends with
@@ -3687,7 +3711,6 @@ static int apply_patch(int fd, const char *filename, int options)
 	struct patch *list = NULL, **listp = &list;
 	int skipped_patch = 0;
 
-	/* FIXME - memory leak when using multiple patch files as inputs */
 	memset(&fn_table, 0, sizeof(struct string_list));
 	patch_input_file = filename;
 	read_patch_file(&buf, fd);
@@ -3712,8 +3735,7 @@ static int apply_patch(int fd, const char *filename, int options)
 			listp = &patch->next;
 		}
 		else {
-			/* perhaps free it a bit better? */
-			free(patch);
+			free_patch(patch);
 			skipped_patch++;
 		}
 		offset += nr;
@@ -3754,6 +3776,8 @@ static int apply_patch(int fd, const char *filename, int options)
 	if (summary)
 		summary_patch_list(list);
 
+	free_patch(list);
+
 	strbuf_release(&buf);
 	return 0;
 }
-- 
1.7.3.4

  parent reply	other threads:[~2012-03-03 14:41 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-03  2:31 [PATCH 0/3] Fix some documented fixmes Jared Hance
2012-03-03  2:31 ` [PATCH 1/3] Use startup_info->prefix rather than prefix Jared Hance
2012-03-03  7:30   ` Junio C Hamano
2012-03-03  9:50     ` Nguyen Thai Ngoc Duy
2012-03-03 21:44       ` Junio C Hamano
2012-03-03 23:23         ` Jared Hance
2012-03-03  2:31 ` [PATCH 2/3] Fix memory leak in apply_patch in apply.c Jared Hance
2012-03-03  7:41   ` Junio C Hamano
2012-03-03  2:31 ` [PATCH 3/3] Add threaded versions of functions in symlinks.c Jared Hance
2012-03-03  7:55   ` Junio C Hamano
2012-03-03 14:40 ` [PATCH v2 0/3] Fix a few documents fixmes Jared Hance
2012-03-03 14:40   ` [PATCH v2 1/3] Use startup_info->prefix rather than prefix Jared Hance
2012-03-03 14:47     ` Jeff Epler
2012-03-03 14:40   ` Jared Hance [this message]
2012-03-03 15:05     ` [PATCH v2 2/3] Fix memory leak in apply_patch in apply.c Jared Hance
2012-03-03 21:51     ` Junio C Hamano
2012-03-03 14:40   ` [PATCH v2 3/3] Add threaded versions of functions in symlinks.c Jared Hance
2012-03-05 11:00     ` Thomas Rast

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e631bb2059c800f9d49eed51cfa5ba4d04106a2e.1330785363.git.jaredhance@gmail.com \
    --to=jaredhance@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).