diff options
author | Jim Meyering <jim@meyering.net> | 2010-10-11 17:41:16 +0200 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2010-10-13 19:11:26 -0700 |
commit | d8d2eb7d6b5e48c2bcb0e71a770f8a05375ac03e (patch) | |
tree | 41e06111449b6afdc469084cff90448acf142307 | |
parent | 7c6eafa35af805578990e76b691ff7f1a25a3c57 (diff) | |
download | git-d8d2eb7d6b5e48c2bcb0e71a770f8a05375ac03e.tar.gz git-d8d2eb7d6b5e48c2bcb0e71a770f8a05375ac03e.tar.xz |
mailmap: fix use of freed memory
On an x86_64 system (F13-based), I ran these commands in an empty directory:
git init
printf '%s\n' \
'<jdoe@example.com> <jdoe@example.COM>' \
'John <jdoe@example.com>' > .mailmap
git shortlog < /dev/null
Here's the result:
(reading log message from standard input)
*** glibc detected *** git: free(): invalid pointer: 0x0000000000f53730 ***
======= Backtrace: =========
/lib64/libc.so.6[0x31ba875676]
git[0x48c2a5]
git[0x4b9858]
...
zsh: abort (core dumped) git shortlog
What happened?
Some .mailmap entry is of the <email1> <email2> form,
while a subsequent one looks like "User Name <Email2>,
and the two email addresses on the right are not identical
but are "equal" when using a case-insensitive comparator.
Then, when add_mapping is processing the latter line, new_email is NULL
and we free me->email, yet do not replace it with a new strdup'd string.
Thus, when later we attempt to use the buffer behind that ->email pointer,
we reference freed memory.
The solution is to free ->email and ->name only if we're about to replace them.
[jc: squashed in the tests from Jonathan]
Signed-off-by: Jim Meyering <meyering@redhat.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | mailmap.c | 10 | ||||
-rwxr-xr-x | t/t4203-mailmap.sh | 41 |
2 files changed, 44 insertions, 7 deletions
@@ -79,12 +79,14 @@ static void add_mapping(struct string_list *map, if (old_name == NULL) { debug_mm("mailmap: adding (simple) entry for %s at index %d\n", old_email, index); /* Replace current name and new email for simple entry */ - free(me->name); - free(me->email); - if (new_name) + if (new_name) { + free(me->name); me->name = xstrdup(new_name); - if (new_email) + } + if (new_email) { + free(me->email); me->email = xstrdup(new_email); + } } else { struct mailmap_info *mi = xmalloc(sizeof(struct mailmap_info)); debug_mm("mailmap: adding (complex) entry for %s at index %d\n", old_email, index); diff --git a/t/t4203-mailmap.sh b/t/t4203-mailmap.sh index 9a7d1b446..f4f82c023 100755 --- a/t/t4203-mailmap.sh +++ b/t/t4203-mailmap.sh @@ -11,6 +11,7 @@ test_expect_success setup ' git commit -m initial && echo two >>one && git add one && + test_tick && git commit --author "nick1 <bugs@company.xx>" -m second ' @@ -54,7 +55,7 @@ Repo Guy (1): EOF test_expect_success 'mailmap.file set' ' - mkdir internal_mailmap && + mkdir -p internal_mailmap && echo "Internal Guy <bugs@company.xx>" > internal_mailmap/.mailmap && git config mailmap.file internal_mailmap/.mailmap && git shortlog HEAD >actual && @@ -93,6 +94,40 @@ test_expect_success 'mailmap.file non-existant' ' ' cat >expect <<\EOF +Internal Guy (1): + second + +Repo Guy (1): + initial + +EOF + +test_expect_success 'name entry after email entry' ' + mkdir -p internal_mailmap && + echo "<bugs@company.xy> <bugs@company.xx>" >internal_mailmap/.mailmap && + echo "Internal Guy <bugs@company.xx>" >>internal_mailmap/.mailmap && + git shortlog >actual && + test_cmp expect actual +' + +cat >expect <<\EOF +Internal Guy (1): + second + +Repo Guy (1): + initial + +EOF + +test_expect_success 'name entry after email entry, case-insensitive' ' + mkdir -p internal_mailmap && + echo "<bugs@company.xy> <bugs@company.xx>" >internal_mailmap/.mailmap && + echo "Internal Guy <BUGS@Company.xx>" >>internal_mailmap/.mailmap && + git shortlog >actual && + test_cmp expect actual +' + +cat >expect <<\EOF A U Thor (1): initial @@ -101,7 +136,7 @@ nick1 (1): EOF test_expect_success 'No mailmap files, but configured' ' - rm .mailmap && + rm -f .mailmap internal_mailmap/.mailmap && git shortlog HEAD >actual && test_cmp expect actual ' @@ -153,7 +188,7 @@ test_expect_success 'Shortlog output (complex mapping)' ' test_tick && git commit --author "CTO <cto@coompany.xx>" -m seventh && - mkdir internal_mailmap && + mkdir -p internal_mailmap && echo "Committed <committer@example.com>" > internal_mailmap/.mailmap && echo "<cto@company.xx> <cto@coompany.xx>" >> internal_mailmap/.mailmap && echo "Some Dude <some@dude.xx> nick1 <bugs@company.xx>" >> internal_mailmap/.mailmap && |