Skip to content

Commit f026358

Browse files
committed
mailmap: always return a plain mail address from map_user()
The callers of map_user() give email and name to it, and expect to get the up-to-date email and/or name to be used in their output. The function rewrites the given buffers in place. To optimize the majority of cases, the function returns 0 when it did not do anything, and it returns 1 when the caller should use the updated contents. The 'email' input to the function is terminated by '>' or a NUL (whichever comes first) for historical reasons, but when a rewrite happens, the value is replaced with the mailbox inside the <> pair. However, it failed to meet this expectation when it only rewrote the name part without rewriting the email part, and the email in the input was terminated by '>'. This causes an extra '>' to appear in the output of "blame -e", because the caller does send in '>'-terminated email, and when the function returned 1 to tell it that rewriting happened, it appends '>' that is necessary when the email part was rewritten. The patch looks bigger than it actually is, because this change makes a variable that points at the end of the email part in the input 'p' live much longer than it used to, deserving a more descriptive name. Noticed and diagnosed by Felipe Contreras and Jeff King. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 04f6785 commit f026358

File tree

1 file changed

+10
-8
lines changed

1 file changed

+10
-8
lines changed

mailmap.c

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,27 +190,27 @@ void clear_mailmap(struct string_list *map)
190190
int map_user(struct string_list *map,
191191
char *email, int maxlen_email, char *name, int maxlen_name)
192192
{
193-
char *p;
193+
char *end_of_email;
194194
struct string_list_item *item;
195195
struct mailmap_entry *me;
196196
char buf[1024], *mailbuf;
197197
int i;
198198

199199
/* figure out space requirement for email */
200-
p = strchr(email, '>');
201-
if (!p) {
200+
end_of_email = strchr(email, '>');
201+
if (!end_of_email) {
202202
/* email passed in might not be wrapped in <>, but end with a \0 */
203-
p = memchr(email, '\0', maxlen_email);
204-
if (!p)
203+
end_of_email = memchr(email, '\0', maxlen_email);
204+
if (!end_of_email)
205205
return 0;
206206
}
207-
if (p - email + 1 < sizeof(buf))
207+
if (end_of_email - email + 1 < sizeof(buf))
208208
mailbuf = buf;
209209
else
210-
mailbuf = xmalloc(p - email + 1);
210+
mailbuf = xmalloc(end_of_email - email + 1);
211211

212212
/* downcase the email address */
213-
for (i = 0; i < p - email; i++)
213+
for (i = 0; i < end_of_email - email; i++)
214214
mailbuf[i] = tolower(email[i]);
215215
mailbuf[i] = 0;
216216

@@ -236,6 +236,8 @@ int map_user(struct string_list *map,
236236
}
237237
if (maxlen_email && mi->email)
238238
strlcpy(email, mi->email, maxlen_email);
239+
else
240+
*end_of_email = '\0';
239241
if (maxlen_name && mi->name)
240242
strlcpy(name, mi->name, maxlen_name);
241243
debug_mm("map_user: to '%s' <%s>\n", name, mi->email ? mi->email : "");

0 commit comments

Comments
 (0)