sscanf/strtoul: parse integers robustly
* builtin-grep.c (strtoul_ui): Move function definition from here, to... * git-compat-util.h (strtoul_ui): ...here, with an added "base" parameter. * builtin-grep.c (cmd_grep): Update use of strtoul_ui to include base, "10". * builtin-update-index.c (read_index_info): Diagnose an invalid mode integer that is out of range or merely larger than INT_MAX. (cmd_update_index): Use strtoul_ui, not sscanf. * convert-objects.c (write_subdirectory): Likewise. Signed-off-by: Jim Meyering <jim@meyering.net> Signed-off-by: Junio C Hamano <junkio@cox.net>maint
							parent
							
								
									e94b4d2f2a
								
							
						
					
					
						commit
						61d6ed139f
					
				|  | @ -434,19 +434,6 @@ static const char emsg_missing_context_len[] = | ||||||
| static const char emsg_missing_argument[] = | static const char emsg_missing_argument[] = | ||||||
| "option requires an argument -%s"; | "option requires an argument -%s"; | ||||||
|  |  | ||||||
| static int strtoul_ui(char const *s, unsigned int *result) |  | ||||||
| { |  | ||||||
| 	unsigned long ul; |  | ||||||
| 	char *p; |  | ||||||
|  |  | ||||||
| 	errno = 0; |  | ||||||
| 	ul = strtoul(s, &p, 10); |  | ||||||
| 	if (errno || *p || p == s || (unsigned int) ul != ul) |  | ||||||
| 		return -1; |  | ||||||
| 	*result = ul; |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| int cmd_grep(int argc, const char **argv, const char *prefix) | int cmd_grep(int argc, const char **argv, const char *prefix) | ||||||
| { | { | ||||||
| 	int hit = 0; | 	int hit = 0; | ||||||
|  | @ -569,7 +556,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix) | ||||||
| 				scan = arg + 1; | 				scan = arg + 1; | ||||||
| 				break; | 				break; | ||||||
| 			} | 			} | ||||||
| 			if (strtoul_ui(scan, &num)) | 			if (strtoul_ui(scan, 10, &num)) | ||||||
| 				die(emsg_invalid_context_len, scan); | 				die(emsg_invalid_context_len, scan); | ||||||
| 			switch (arg[1]) { | 			switch (arg[1]) { | ||||||
| 			case 'A': | 			case 'A': | ||||||
|  |  | ||||||
|  | @ -227,6 +227,7 @@ static void read_index_info(int line_termination) | ||||||
| 		char *path_name; | 		char *path_name; | ||||||
| 		unsigned char sha1[20]; | 		unsigned char sha1[20]; | ||||||
| 		unsigned int mode; | 		unsigned int mode; | ||||||
|  | 		unsigned long ul; | ||||||
| 		int stage; | 		int stage; | ||||||
|  |  | ||||||
| 		/* This reads lines formatted in one of three formats: | 		/* This reads lines formatted in one of three formats: | ||||||
|  | @ -249,9 +250,12 @@ static void read_index_info(int line_termination) | ||||||
| 		if (buf.eof) | 		if (buf.eof) | ||||||
| 			break; | 			break; | ||||||
|  |  | ||||||
| 		mode = strtoul(buf.buf, &ptr, 8); | 		errno = 0; | ||||||
| 		if (ptr == buf.buf || *ptr != ' ') | 		ul = strtoul(buf.buf, &ptr, 8); | ||||||
|  | 		if (ptr == buf.buf || *ptr != ' ' | ||||||
|  | 		    || errno || (unsigned int) ul != ul) | ||||||
| 			goto bad_line; | 			goto bad_line; | ||||||
|  | 		mode = ul; | ||||||
|  |  | ||||||
| 		tab = strchr(ptr, '\t'); | 		tab = strchr(ptr, '\t'); | ||||||
| 		if (!tab || tab - ptr < 41) | 		if (!tab || tab - ptr < 41) | ||||||
|  | @ -547,7 +551,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) | ||||||
| 				if (i+3 >= argc) | 				if (i+3 >= argc) | ||||||
| 					die("git-update-index: --cacheinfo <mode> <sha1> <path>"); | 					die("git-update-index: --cacheinfo <mode> <sha1> <path>"); | ||||||
|  |  | ||||||
| 				if ((sscanf(argv[i+1], "%o", &mode) != 1) || | 				if ((strtoul_ui(argv[i+1], 8, &mode) != 1) || | ||||||
| 				    get_sha1_hex(argv[i+2], sha1) || | 				    get_sha1_hex(argv[i+2], sha1) || | ||||||
| 				    add_cacheinfo(mode, sha1, argv[i+3], 0)) | 				    add_cacheinfo(mode, sha1, argv[i+3], 0)) | ||||||
| 					die("git-update-index: --cacheinfo" | 					die("git-update-index: --cacheinfo" | ||||||
|  |  | ||||||
|  | @ -88,7 +88,7 @@ static int write_subdirectory(void *buffer, unsigned long size, const char *base | ||||||
| 		unsigned int mode; | 		unsigned int mode; | ||||||
| 		char *slash, *origpath; | 		char *slash, *origpath; | ||||||
|  |  | ||||||
| 		if (!path || sscanf(buffer, "%o", &mode) != 1) | 		if (!path || strtoul_ui(buffer, 8, &mode) != 1) | ||||||
| 			die("bad tree conversion"); | 			die("bad tree conversion"); | ||||||
| 		mode = convert_mode(mode); | 		mode = convert_mode(mode); | ||||||
| 		path++; | 		path++; | ||||||
|  |  | ||||||
|  | @ -301,4 +301,17 @@ static inline int prefixcmp(const char *str, const char *prefix) | ||||||
| 	return strncmp(str, prefix, strlen(prefix)); | 	return strncmp(str, prefix, strlen(prefix)); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static inline int strtoul_ui(char const *s, int base, unsigned int *result) | ||||||
|  | { | ||||||
|  | 	unsigned long ul; | ||||||
|  | 	char *p; | ||||||
|  |  | ||||||
|  | 	errno = 0; | ||||||
|  | 	ul = strtoul(s, &p, base); | ||||||
|  | 	if (errno || *p || p == s || (unsigned int) ul != ul) | ||||||
|  | 		return -1; | ||||||
|  | 	*result = ul; | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Jim Meyering
						Jim Meyering