worktree: check the result of read_in_full()
We try to read "len" bytes into a buffer and just assume that it happened correctly. In practice this should usually be the case, since we just stat'd the file to get the length. But we could be fooled by transient errors or by other processes racily truncating the file. Let's be more careful. There's a slim chance this could catch a real error, but it also prevents people and tools from getting worried while reading the code. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
		 Jeff King
					Jeff King
				
			
				
					committed by
					
						 Junio C Hamano
						Junio C Hamano
					
				
			
			
				
	
			
			
			 Junio C Hamano
						Junio C Hamano
					
				
			
						parent
						
							228740b67b
						
					
				
				
					commit
					8a1a8d2ad1
				
			| @ -40,6 +40,7 @@ static int prune_worktree(const char *id, struct strbuf *reason) | |||||||
| 	char *path; | 	char *path; | ||||||
| 	int fd; | 	int fd; | ||||||
| 	size_t len; | 	size_t len; | ||||||
|  | 	ssize_t read_result; | ||||||
|  |  | ||||||
| 	if (!is_directory(git_path("worktrees/%s", id))) { | 	if (!is_directory(git_path("worktrees/%s", id))) { | ||||||
| 		strbuf_addf(reason, _("Removing worktrees/%s: not a valid directory"), id); | 		strbuf_addf(reason, _("Removing worktrees/%s: not a valid directory"), id); | ||||||
| @ -59,8 +60,24 @@ static int prune_worktree(const char *id, struct strbuf *reason) | |||||||
| 	} | 	} | ||||||
| 	len = xsize_t(st.st_size); | 	len = xsize_t(st.st_size); | ||||||
| 	path = xmallocz(len); | 	path = xmallocz(len); | ||||||
| 	read_in_full(fd, path, len); |  | ||||||
|  | 	read_result = read_in_full(fd, path, len); | ||||||
|  | 	if (read_result < 0) { | ||||||
|  | 		strbuf_addf(reason, _("Removing worktrees/%s: unable to read gitdir file (%s)"), | ||||||
|  | 			    id, strerror(errno)); | ||||||
|  | 		close(fd); | ||||||
|  | 		free(path); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
| 	close(fd); | 	close(fd); | ||||||
|  |  | ||||||
|  | 	if (read_result != len) { | ||||||
|  | 		strbuf_addf(reason, | ||||||
|  | 			    _("Removing worktrees/%s: short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"), | ||||||
|  | 			    id, (uintmax_t)len, (uintmax_t)read_result); | ||||||
|  | 		free(path); | ||||||
|  | 		return 1; | ||||||
|  | 	} | ||||||
| 	while (len && (path[len - 1] == '\n' || path[len - 1] == '\r')) | 	while (len && (path[len - 1] == '\n' || path[len - 1] == '\r')) | ||||||
| 		len--; | 		len--; | ||||||
| 	if (!len) { | 	if (!len) { | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user