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 <gitster@pobox.com>maint
							parent
							
								
									04f6785a08
								
							
						
					
					
						commit
						f026358ef2
					
				
							
								
								
									
										18
									
								
								mailmap.c
								
								
								
								
							
							
						
						
									
										18
									
								
								mailmap.c
								
								
								
								
							|  | @ -190,27 +190,27 @@ void clear_mailmap(struct string_list *map) | ||||||
| int map_user(struct string_list *map, | int map_user(struct string_list *map, | ||||||
| 	     char *email, int maxlen_email, char *name, int maxlen_name) | 	     char *email, int maxlen_email, char *name, int maxlen_name) | ||||||
| { | { | ||||||
| 	char *p; | 	char *end_of_email; | ||||||
| 	struct string_list_item *item; | 	struct string_list_item *item; | ||||||
| 	struct mailmap_entry *me; | 	struct mailmap_entry *me; | ||||||
| 	char buf[1024], *mailbuf; | 	char buf[1024], *mailbuf; | ||||||
| 	int i; | 	int i; | ||||||
|  |  | ||||||
| 	/* figure out space requirement for email */ | 	/* figure out space requirement for email */ | ||||||
| 	p = strchr(email, '>'); | 	end_of_email = strchr(email, '>'); | ||||||
| 	if (!p) { | 	if (!end_of_email) { | ||||||
| 		/* email passed in might not be wrapped in <>, but end with a \0 */ | 		/* email passed in might not be wrapped in <>, but end with a \0 */ | ||||||
| 		p = memchr(email, '\0', maxlen_email); | 		end_of_email = memchr(email, '\0', maxlen_email); | ||||||
| 		if (!p) | 		if (!end_of_email) | ||||||
| 			return 0; | 			return 0; | ||||||
| 	} | 	} | ||||||
| 	if (p - email + 1 < sizeof(buf)) | 	if (end_of_email - email + 1 < sizeof(buf)) | ||||||
| 		mailbuf = buf; | 		mailbuf = buf; | ||||||
| 	else | 	else | ||||||
| 		mailbuf = xmalloc(p - email + 1); | 		mailbuf = xmalloc(end_of_email - email + 1); | ||||||
|  |  | ||||||
| 	/* downcase the email address */ | 	/* downcase the email address */ | ||||||
| 	for (i = 0; i < p - email; i++) | 	for (i = 0; i < end_of_email - email; i++) | ||||||
| 		mailbuf[i] = tolower(email[i]); | 		mailbuf[i] = tolower(email[i]); | ||||||
| 	mailbuf[i] = 0; | 	mailbuf[i] = 0; | ||||||
|  |  | ||||||
|  | @ -236,6 +236,8 @@ int map_user(struct string_list *map, | ||||||
| 		} | 		} | ||||||
| 		if (maxlen_email && mi->email) | 		if (maxlen_email && mi->email) | ||||||
| 			strlcpy(email, mi->email, maxlen_email); | 			strlcpy(email, mi->email, maxlen_email); | ||||||
|  | 		else | ||||||
|  | 			*end_of_email = '\0'; | ||||||
| 		if (maxlen_name && mi->name) | 		if (maxlen_name && mi->name) | ||||||
| 			strlcpy(name, mi->name, maxlen_name); | 			strlcpy(name, mi->name, maxlen_name); | ||||||
| 		debug_mm("map_user:  to '%s' <%s>\n", name, mi->email ? mi->email : ""); | 		debug_mm("map_user:  to '%s' <%s>\n", name, mi->email ? mi->email : ""); | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano