threads / patch / 34732

patchmailmap: fix check for freeing memory

Subject: [PATCH] mailmap: fix check for freeing memory

## tl;dr

12 messages between Aug 20, 2013 and Aug 20, 2013. Diffs are folded; open one to read it.

replies: 11people: 4as markdown or json

Stefan Beller· Aug 20, 2013, 13:22 UTC · lore

The condition as it is written in that line was most likely intended to check for the pointer passed to free(), rather than checking for the 'repo_abbrev', which is already checked against being non null at the beginning of the function.

Signed-off-by: Stefan Beller <stefanbeller@googlemail.com>
---
 mailmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Show changes to mailmap.c +1 −1
diff --git a/mailmap.c b/mailmap.c
index 44614fc..36d2a7a 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -139,35 +139,35 @@ static char *parse_name_and_email(char *buffer, char **name,
 static void read_mailmap_line(struct string_list *map, char *buffer,
 			      char **repo_abbrev)
 {
 	char *name1 = NULL, *email1 = NULL, *name2 = NULL, *email2 = NULL;
 	if (buffer[0] == '#') {
 		static const char abbrev[] = "# repo-abbrev:";
 		int abblen = sizeof(abbrev) - 1;
 		int len = strlen(buffer);
 
 		if (!repo_abbrev)
 			return;
 
 		if (len && buffer[len - 1] == '\n')
 			buffer[--len] = 0;
 		if (!strncmp(buffer, abbrev, abblen)) {
 			char *cp;
 
-			if (repo_abbrev)
+			if (*repo_abbrev)
 				free(*repo_abbrev);
 			*repo_abbrev = xmalloc(len);
 
 			for (cp = buffer + abblen; isspace(*cp); cp++)
 				; /* nothing */
 			strcpy(*repo_abbrev, cp);
 		}
 		return;
 	}
 	if ((name2 = parse_name_and_email(buffer, &name1, &email1, 0)) != NULL)
 		parse_name_and_email(name2, &name2, &email2, 1);
 
 	if (email1)
 		add_mapping(map, name1, email1, name2, email2);
 }
 
 static int read_mailmap_file(struct string_list *map, const char *filename,
-- 
1.8.4.rc3.1.gc1ebd90
Thomas Rast· Aug 20, 2013, 13:40 UTC · re: Stefan Beller · lore

Re: [PATCH] mailmap: fix check for freeing memory

Stefan Beller <stefanbeller@googlemail.com> writes:
> The condition as it is written in that line was most likely intended to
> check for the pointer passed to free(), rather than checking for the
> 'repo_abbrev', which is already checked against being non null at the
> beginning of the function.
[...]
> -			if (repo_abbrev)
> +			if (*repo_abbrev)
>  				free(*repo_abbrev);

But now the test is useless, because free(NULL) is defined to be a no-op.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch
Jeff King· Aug 20, 2013, 13:52 UTC · re: Thomas Rast · lore

Re: [PATCH] mailmap: fix check for freeing memory

On Tue, Aug 20, 2013 at 03:40:02PM +0200, Thomas Rast wrote:
Show 13 quoted lines
> Stefan Beller <stefanbeller@googlemail.com> writes:
> 
> > The condition as it is written in that line was most likely intended to
> > check for the pointer passed to free(), rather than checking for the
> > 'repo_abbrev', which is already checked against being non null at the
> > beginning of the function.
> [...]
> > -			if (repo_abbrev)
> > +			if (*repo_abbrev)
> >  				free(*repo_abbrev);
> 
> But now the test is useless, because free(NULL) is defined to be a
> no-op.
Yeah, I think we should just drop the conditional completely.

I am not sure of the complete back-story. The earlier check for repo_abbrev to be non-NULL was added by 8503ee4, after this check on free() already existed. So that was when this conditional became redundant.

But the line right after this one unconditionally assigns to "*repo_abbrev", so we would always segfault in such a case anyway (which is what 8503ee4 was fixing).

So I think it was either a misguided "don't pass NULL to free" check that was simply wrong, or it was an incomplete "make sure repo_abbrev is not NULL" check. And the first is useless, and the second is now redundant due to 8503ee4. So it should simply be free().

-Peff
Stefan Beller· Aug 20, 2013, 14:17 UTC · re: Thomas Rast · lore

Re: [PATCH] mailmap: fix check for freeing memory

On 08/20/2013 03:40 PM, Thomas Rast wrote:
Show 14 quoted lines
> Stefan Beller <stefanbeller@googlemail.com> writes:
> 
>> The condition as it is written in that line was most likely intended to
>> check for the pointer passed to free(), rather than checking for the
>> 'repo_abbrev', which is already checked against being non null at the
>> beginning of the function.
> [...]
>> -			if (repo_abbrev)
>> +			if (*repo_abbrev)
>>  				free(*repo_abbrev);
> 
> But now the test is useless, because free(NULL) is defined to be a
> no-op.
> 
Yes, indeed. Thanks for reviewing.

Stepping two steps back, I am trying to figure out, what this repo_abrev thing is doing, as I could find no documentation.

It's passed as a double pointer as declared in mailmap.h: int read_mailmap(struct string_list *map, char **repo_abbrev);

However grepping for "read_mailmap(" (bracket to prevent finding 
read_mailmap_XXX as often used in mailmap.c itself) 
	grep -nHIirF --exclude-dir=.git -- "read_mailmap("
throughout all the sources I just find one occurence having the
second argument not being 'NULL' and that is in 
	builtin/shortlog.c:212:	read_mailmap(&log->mailmap, &log->common_repo_prefix);
which turns out to be:
void shortlog_init(struct shortlog *log)
{
	memset(log, 0, sizeof(*log));
	read_mailmap(&log->mailmap, &log->common_repo_prefix);
	...

So we're passing there an address, which was just set to zero. This is the only occurence of passing a value at all and the value being passed is 0, so the free in the original patch doesn't need that check either.

As I am resending the patch, could somebody please explain me the mechanism of the "# repo-abbrev:" line? Even git itself doesn't use it in the .mailmap file, but a quick google search shows up only kernel repositories.

Stefan
Stefan Beller· Aug 20, 2013, 14:18 UTC · re: Stefan Beller · lore

[PATCH] mailmap: remove redundant check for freeing memory

The condition as it is written in that line has already been checked in the beginning of the function, which was introduced in 8503ee4 (2007-05-01, Fix read_mailmap to handle a caller uninterested in repo abbreviation)

Helped-by: Jeff King <peff@peff.net>
Helped-by: Thomas Rast <trast@inf.ethz.ch>
Signed-off-by: Stefan Beller <stefanbeller@googlemail.com>
---
 mailmap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
Show changes to mailmap.c +1 −2
diff --git a/mailmap.c b/mailmap.c
index 44614fc..7d5caa6 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -153,8 +153,7 @@ static void read_mailmap_line(struct string_list *map, char *buffer,
 		if (!strncmp(buffer, abbrev, abblen)) {
 			char *cp;
 
-			if (repo_abbrev)
-				free(*repo_abbrev);
+			free(*repo_abbrev);
 			*repo_abbrev = xmalloc(len);
 
 			for (cp = buffer + abblen; isspace(*cp); cp++)
-- 
1.8.4.rc3.1.gc1ebd90
Jeff King· Aug 20, 2013, 14:28 UTC · re: Stefan Beller · lore

Re: [PATCH] mailmap: remove redundant check for freeing memory

On Tue, Aug 20, 2013 at 04:18:00PM +0200, Stefan Beller wrote:
Show 9 quoted lines
> The condition as it is written in that line has already been checked
> in the beginning of the function, which was introduced in
> 8503ee4 (2007-05-01, Fix read_mailmap to handle a caller uninterested
> in repo abbreviation)
> 
> Helped-by: Jeff King <peff@peff.net>
> Helped-by: Thomas Rast <trast@inf.ethz.ch>
> Signed-off-by: Stefan Beller <stefanbeller@googlemail.com>
> ---
This version looks good to me.  Thanks.
-Peff
Thomas Rast· Aug 20, 2013, 14:23 UTC · re: Stefan Beller · lore

Re: [PATCH] mailmap: fix check for freeing memory

Stefan Beller <stefanbeller@googlemail.com> writes:
> As I am resending the patch, could somebody please explain me
> the mechanism of the "# repo-abbrev:" line? Even git itself doesn't
> use it in the .mailmap file, but a quick google search shows up only
> kernel repositories.

I had no idea (we really lack documentation on this), but some history digging shows this:

  commit 7595e2ee6ef9b35ebc8dc45543723e1d89765ce3
  Author: Junio C Hamano <junkio@cox.net>
  Date:   Sat Nov 25 00:07:54 2006 -0800
      git-shortlog: make common repository prefix configurable with .mailmap
      
      The code had "/pub/scm/linux/kernel/git/" hardcoded which was
      too specific to the kernel project.
      
      With this, a line in the .mailmap file:
      
          # repo-abbrev: /pub/scm/linux/kernel/git/
      
      can be used to cause the substring to be abbreviated to /.../
      on the title line of the commit message.
      
      Signed-off-by: Junio C Hamano <junkio@cox.net>

It apparently serves to abbreviate commits coming from pull requests, with a subject like

  Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
-- 
Thomas Rast
trast@{inf,student}.ethz.ch
Stefan Beller· Aug 20, 2013, 14:38 UTC · re: Thomas Rast · lore

Re: [PATCH] mailmap: fix check for freeing memory

On 08/20/2013 04:23 PM, Thomas Rast wrote:
Show 33 quoted lines
> Stefan Beller <stefanbeller@googlemail.com> writes:
> 
>> As I am resending the patch, could somebody please explain me
>> the mechanism of the "# repo-abbrev:" line? Even git itself doesn't
>> use it in the .mailmap file, but a quick google search shows up only
>> kernel repositories.
> 
> I had no idea (we really lack documentation on this), but some history
> digging shows this:
> 
>   commit 7595e2ee6ef9b35ebc8dc45543723e1d89765ce3
>   Author: Junio C Hamano <junkio@cox.net>
>   Date:   Sat Nov 25 00:07:54 2006 -0800
> 
>       git-shortlog: make common repository prefix configurable with .mailmap
>       
>       The code had "/pub/scm/linux/kernel/git/" hardcoded which was
>       too specific to the kernel project.
>       
>       With this, a line in the .mailmap file:
>       
>           # repo-abbrev: /pub/scm/linux/kernel/git/
>       
>       can be used to cause the substring to be abbreviated to /.../
>       on the title line of the commit message.
>       
>       Signed-off-by: Junio C Hamano <junkio@cox.net>
> 
> It apparently serves to abbreviate commits coming from pull requests,
> with a subject like
> 
>   Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux
> 
Thanks for looking through the history, I need to adapt my search patterns. ;)

Personally I have the feel this is a very kernel specific, but also useful thing to have. So I would definitely not drop it, but maybe move it to another place, such as in the .git/config file. Then anybody can configure it themselves and maybe even have multiple abbreviation lines possible. It's very likely nowadays that there are repos at various different hosting sites, so just one abbreviation would not cut it anymore.

Or as Jeff just mentioned in his email, it's there for historical purpose, but not needed anymore as git-merge produces nicer commit messages there.

As proposed I checked recent kernel history and saw:

$ git log --min-parents=2 --oneline d6a5e06 Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes 7067552 Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip e91dade Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip fbf2184 Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux 3387ed8 Merge tag 'drm-intel-fixes-2013-08-15' of git://people.freedesktop.org/~danvet/drm-intel d2b2c08 Merge branch 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux 50e37cc Merge branch 'for-3.11-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup a08797e Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4 2620bf0 Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm 359d16c Merge branch 'for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k 0f7dd1a Merge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mturquette/linux 2d2843e Merge tag 'pm-3.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm f43c606 Merge tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound 89cb9ae Merge tag 'usb-3.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

in their .mailmap it read:
	# repo-abbrev: /pub/scm/linux/kernel/git/

So the abbreviation doesn't take place, can this feature be turned off? I'm still confused by that feature.

Thanks, Stefan

Jeff King· Aug 20, 2013, 16:12 UTC · re: Stefan Beller · lore

Re: [PATCH] mailmap: fix check for freeing memory

On Tue, Aug 20, 2013 at 04:38:17PM +0200, Stefan Beller wrote:
Show 23 quoted lines
> As proposed I checked recent kernel history and saw:
> 
> $ git log --min-parents=2 --oneline 
> d6a5e06 Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-fixes
> 7067552 Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
> e91dade Merge branch 'timers-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
> fbf2184 Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
> 3387ed8 Merge tag 'drm-intel-fixes-2013-08-15' of git://people.freedesktop.org/~danvet/drm-intel
> d2b2c08 Merge branch 'drm-fixes-3.11' of git://people.freedesktop.org/~agd5f/linux
> 50e37cc Merge branch 'for-3.11-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup
> a08797e Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
> 2620bf0 Merge branch 'fixes' of git://git.linaro.org/people/rmk/linux-arm
> 359d16c Merge branch 'for-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k
> 0f7dd1a Merge tag 'clk-fixes-for-linus' of git://git.linaro.org/people/mturquette/linux
> 2d2843e Merge tag 'pm-3.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
> f43c606 Merge tag 'sound-3.11' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
> 89cb9ae Merge tag 'usb-3.11-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
> 
> in their .mailmap it read:
> 	# repo-abbrev: /pub/scm/linux/kernel/git/
> 
> So the abbreviation doesn't take place, can this feature be turned off?
> I'm still confused by that feature.

It _only_ impacts git-shortlog, not git-log or other traversals. Making it an even more dubious feature, IMHO.

-Peff
Junio C Hamano· Aug 20, 2013, 17:18 UTC · re: Jeff King · lore

Re: [PATCH] mailmap: fix check for freeing memory

Jeff King <peff@peff.net> writes:
> It _only_ impacts git-shortlog, not git-log or other traversals. Making
> it an even more dubious feature, IMHO.
I think this was done by an explicit end user request for shortlog.

As you mentioned, merge gives readable merge log messages, but it deliberately uses the real URL, not your personal nickname for the remote when writing the title line of a merge, i.e.

	Merge [branch <x> of ]<repoURL>

so it would be helped by the repository abbreviation. It probably was an oversight that we did not extend it to the rest of the log family.

Jeff King· Aug 20, 2013, 17:45 UTC · re: Junio C Hamano · lore

Re: [PATCH] mailmap: fix check for freeing memory

On Tue, Aug 20, 2013 at 10:18:08AM -0700, Junio C Hamano wrote:
Show 9 quoted lines
> As you mentioned, merge gives readable merge log messages, but it
> deliberately uses the real URL, not your personal nickname for the
> remote when writing the title line of a merge, i.e.
> 
> 	Merge [branch <x> of ]<repoURL>
> 
> so it would be helped by the repository abbreviation.  It probably
> was an oversight that we did not extend it to the rest of the log
> family.

Ah, yeah, I suppose git-pull will still do that. I was thinking of a direct git-merge of a tracking branch, which would end up with:

  Merge remote-tracking branch 'origin/master'
whereas "git pull origin master" in the same case would say:
  Merge branch 'master' of git://github.com/gitster/git

Still, I do not think anybody but the kernel is using it. Most people simply have shorter URLs that do not need abbreviated (e.g., the GitHub one shown above). And searching for instances on GitHub yields only the kernel:

  https://github.com/search?q=repo-abbrev+path%3A.mailmap&type=Code

Anyway, I am not proposing ripping the feature out. It just seems like it does not have a lot of users, and it is not worth worrying much about trying to extend it.

-Peff
Jeff King· Aug 20, 2013, 14:27 UTC · re: Stefan Beller · lore

Re: [PATCH] mailmap: fix check for freeing memory

On Tue, Aug 20, 2013 at 04:17:07PM +0200, Stefan Beller wrote:
> Stepping two steps back, I am trying to figure out, what this repo_abrev
> thing is doing, as I could find no documentation.

It's meant to abbreviate long pathnames in subject lines. As you noted, the kernel .mailmap has:

  # repo-abbrev: /pub/scm/linux/kernel/git/
Try "git shortlog" in the kernel and grep for "..." to see its effect.

It is IMHO a misfeature to have it as part of .mailmap, but it is there for historical reasons. And I think it is not really needed these days anyway, as the messages created by git-merge are nicer to read in the first place (and people tend to use nice readable URLs for accessing one-off git pulls, too).

> So we're passing there an address, which was just set to zero.
> This is the only occurence of passing a value at all and the value
> being passed is 0, so the free in the original patch doesn't need
> that check either.

Right. I think the intent was to free a previously found repo-abbrev line to avoid leaking memory (although arguably, it would make sense to keep a list and abbreviate all that we find, I don't think anybody cares anymore for the reasons I stated above).

-Peff

← back to recent threads