summaryrefslogtreecommitdiff
path: root/mailmap.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2010-10-11 15:41:16 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-10-14 02:11:26 (GMT)
commitd8d2eb7d6b5e48c2bcb0e71a770f8a05375ac03e (patch)
tree41e06111449b6afdc469084cff90448acf142307 /mailmap.c
parent7c6eafa35af805578990e76b691ff7f1a25a3c57 (diff)
downloadgit-d8d2eb7d6b5e48c2bcb0e71a770f8a05375ac03e.zip
git-d8d2eb7d6b5e48c2bcb0e71a770f8a05375ac03e.tar.gz
git-d8d2eb7d6b5e48c2bcb0e71a770f8a05375ac03e.tar.bz2
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>
Diffstat (limited to 'mailmap.c')
-rw-r--r--mailmap.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/mailmap.c b/mailmap.c
index f80b701..02fcfde 100644
--- a/mailmap.c
+++ b/mailmap.c
@@ -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);