unique_path: fix unlikely heap overflow
When merge-recursive creates a unique filename, it uses a template like: path~branch_%d where the final "_%d" is filled by an incrementing counter until we find a unique name. We allocate 8 characters for the counter, but there is no logic to limit the size of the integer. Of course, this is extremely unlikely, as you would need a hundred million collisions to trigger the problem. Even if an attacker constructed a specialized repo, it is unlikely that the victim would have the patience to run the merge. However, we can make it trivially correct (and hopefully more readable) by using a strbuf. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									f33206992d
								
							
						
					
					
						commit
						45bc131dd3
					
				|  | @ -601,25 +601,36 @@ static int remove_file(struct merge_options *o, int clean, | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* add a string to a strbuf, but converting "/" to "_" */ | ||||||
|  | static void add_flattened_path(struct strbuf *out, const char *s) | ||||||
|  | { | ||||||
|  | 	size_t i = out->len; | ||||||
|  | 	strbuf_addstr(out, s); | ||||||
|  | 	for (; i < out->len; i++) | ||||||
|  | 		if (out->buf[i] == '/') | ||||||
|  | 			out->buf[i] = '_'; | ||||||
|  | } | ||||||
|  |  | ||||||
| static char *unique_path(struct merge_options *o, const char *path, const char *branch) | static char *unique_path(struct merge_options *o, const char *path, const char *branch) | ||||||
| { | { | ||||||
| 	char *newpath = xmalloc(strlen(path) + 1 + strlen(branch) + 8 + 1); | 	struct strbuf newpath = STRBUF_INIT; | ||||||
| 	int suffix = 0; | 	int suffix = 0; | ||||||
| 	struct stat st; | 	struct stat st; | ||||||
| 	char *p = newpath + strlen(path); | 	size_t base_len; | ||||||
| 	strcpy(newpath, path); |  | ||||||
| 	*(p++) = '~'; |  | ||||||
| 	strcpy(p, branch); |  | ||||||
| 	for (; *p; ++p) |  | ||||||
| 		if ('/' == *p) |  | ||||||
| 			*p = '_'; |  | ||||||
| 	while (string_list_has_string(&o->current_file_set, newpath) || |  | ||||||
| 	       string_list_has_string(&o->current_directory_set, newpath) || |  | ||||||
| 	       lstat(newpath, &st) == 0) |  | ||||||
| 		sprintf(p, "_%d", suffix++); |  | ||||||
|  |  | ||||||
| 	string_list_insert(&o->current_file_set, newpath); | 	strbuf_addf(&newpath, "%s~", path); | ||||||
| 	return newpath; | 	add_flattened_path(&newpath, branch); | ||||||
|  |  | ||||||
|  | 	base_len = newpath.len; | ||||||
|  | 	while (string_list_has_string(&o->current_file_set, newpath.buf) || | ||||||
|  | 	       string_list_has_string(&o->current_directory_set, newpath.buf) || | ||||||
|  | 	       lstat(newpath.buf, &st) == 0) { | ||||||
|  | 		strbuf_setlen(&newpath, base_len); | ||||||
|  | 		strbuf_addf(&newpath, "_%d", suffix++); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	string_list_insert(&o->current_file_set, newpath.buf); | ||||||
|  | 	return strbuf_detach(&newpath, NULL); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int dir_in_way(const char *path, int check_working_copy) | static int dir_in_way(const char *path, int check_working_copy) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Jeff King
						Jeff King