[PATCH 01/11] rev-parse: fix a leak with --abbrev-ref

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



To handle "--abbrev-ref" we use shorten_unambiguous_ref().  This
function takes a refname and returns a shortened refname, which is a
newly allocated string that needs to be freed.

Unfortunately, the refname variable is reused to receive the shortened
one.  Therefore, we lose the original refname, which needs to be freed
as well, producing a leak.

This leak can be reviewed with:

   $ for a in {1..10}; do git branch foo_${a}; done
   $ git rev-parse --abbrev-ref refs/heads/foo_{1..10}

   Direct leak of 171 byte(s) in 10 object(s) allocated from:
       ... in xstrdup wrapper.c
       ... in expand_ref refs.c
       ... in repo_dwim_ref refs.c
       ... in show_rev builtin/rev-parse.c
       ... in cmd_rev_parse builtin/rev-parse.c
       ... in run_builtin git.c

We have this leak since a45d34691e (rev-parse: --abbrev-ref option to
shorten ref name, 2009-04-13) when "--abbrev-ref" was introduced.

Let's fix it.

Signed-off-by: Rubén Justo <rjusto@xxxxxxxxx>
---
 builtin/rev-parse.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 852e49e340..9fd7095431 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -141,7 +141,7 @@ static void show_rev(int type, const struct object_id *oid, const char *name)
 	if ((symbolic || abbrev_ref) && name) {
 		if (symbolic == SHOW_SYMBOLIC_FULL || abbrev_ref) {
 			struct object_id discard;
-			char *full;
+			char *full, *to_free = NULL;
 
 			switch (repo_dwim_ref(the_repository, name,
 					      strlen(name), &discard, &full,
@@ -156,9 +156,11 @@ static void show_rev(int type, const struct object_id *oid, const char *name)
 				 */
 				break;
 			case 1: /* happy */
-				if (abbrev_ref)
+				if (abbrev_ref) {
+					to_free = full;
 					full = shorten_unambiguous_ref(full,
 						abbrev_ref_strict);
+				}
 				show_with_type(type, full);
 				break;
 			default: /* ambiguous */
@@ -166,6 +168,7 @@ static void show_rev(int type, const struct object_id *oid, const char *name)
 				break;
 			}
 			free(full);
+			free(to_free);
 		} else {
 			show_with_type(type, name);
 		}
-- 
2.40.1



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux