Test and fix normalize_path_copy()
This changes the test-path-utils utility to invoke normalize_path_copy() instead of normalize_absolute_path() because the latter is about to be removed. The test cases in t0060 are adjusted in two regards: - normalize_path_copy() more often leaves a trailing slash in the result. This has no negative side effects because the new user of this function, longest_ancester_length(), already accounts for this behavior. - The function can fail. The tests uncover a flaw in normalize_path_copy(): If there are sufficiently many '..' path components so that the root is reached, such as in "/d1/s1/../../d2", then the leading slash was lost. This manifested itself that (assuming there is a repository at /tmp/foo) $ git add /d1/../tmp/foo/some-file reported 'pathspec is outside repository'. This is now fixed. Moreover, the test case descriptions of t0060 now include the test data and expected outcome. Signed-off-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									43a7ddb55d
								
							
						
					
					
						commit
						f42302b493
					
				
							
								
								
									
										16
									
								
								path.c
								
								
								
								
							
							
						
						
									
										16
									
								
								path.c
								
								
								
								
							|  | @ -484,18 +484,12 @@ int normalize_path_copy(char *dst, const char *src) | ||||||
| 		 * dst0..dst is prefix portion, and dst[-1] is '/'; | 		 * dst0..dst is prefix portion, and dst[-1] is '/'; | ||||||
| 		 * go up one level. | 		 * go up one level. | ||||||
| 		 */ | 		 */ | ||||||
| 		dst -= 2; /* go past trailing '/' if any */ | 		dst--;	/* go to trailing '/' */ | ||||||
| 		if (dst < dst0) | 		if (dst <= dst0) | ||||||
| 			return -1; | 			return -1; | ||||||
| 		while (1) { | 		/* Windows: dst[-1] cannot be backslash anymore */ | ||||||
| 			if (dst <= dst0) | 		while (dst0 < dst && dst[-1] != '/') | ||||||
| 				break; | 			dst--; | ||||||
| 			c = *dst--; |  | ||||||
| 			if (c == '/') {	/* MinGW: cannot be '\\' anymore */ |  | ||||||
| 				dst += 2; |  | ||||||
| 				break; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 	*dst = '\0'; | 	*dst = '\0'; | ||||||
| 	return 0; | 	return 0; | ||||||
|  |  | ||||||
|  | @ -8,36 +8,37 @@ test_description='Test various path utilities' | ||||||
| . ./test-lib.sh | . ./test-lib.sh | ||||||
|  |  | ||||||
| norm_abs() { | norm_abs() { | ||||||
| 	test_expect_success "normalize absolute" \ | 	test_expect_success "normalize absolute: $1 => $2" \ | ||||||
| 	"test \$(test-path-utils normalize_absolute_path '$1') = '$2'" | 	"test \"\$(test-path-utils normalize_path_copy '$1')\" = '$2'" | ||||||
| } | } | ||||||
|  |  | ||||||
| ancestor() { | ancestor() { | ||||||
| 	test_expect_success "longest ancestor" \ | 	test_expect_success "longest ancestor: $1 $2 => $3" \ | ||||||
| 	"test \$(test-path-utils longest_ancestor_length '$1' '$2') = '$3'" | 	"test \"\$(test-path-utils longest_ancestor_length '$1' '$2')\" = '$3'" | ||||||
| } | } | ||||||
|  |  | ||||||
| norm_abs "" / | norm_abs "" "" | ||||||
| norm_abs / / | norm_abs / / | ||||||
| norm_abs // / | norm_abs // / | ||||||
| norm_abs /// / | norm_abs /// / | ||||||
| norm_abs /. / | norm_abs /. / | ||||||
| norm_abs /./ / | norm_abs /./ / | ||||||
| norm_abs /./.. / | norm_abs /./.. ++failed++ | ||||||
| norm_abs /../. / | norm_abs /../. ++failed++ | ||||||
| norm_abs /./../.// / | norm_abs /./../.// ++failed++ | ||||||
| norm_abs /dir/.. / | norm_abs /dir/.. / | ||||||
| norm_abs /dir/sub/../.. / | norm_abs /dir/sub/../.. / | ||||||
|  | norm_abs /dir/sub/../../.. ++failed++ | ||||||
| norm_abs /dir /dir | norm_abs /dir /dir | ||||||
| norm_abs /dir// /dir | norm_abs /dir// /dir/ | ||||||
| norm_abs /./dir /dir | norm_abs /./dir /dir | ||||||
| norm_abs /dir/. /dir | norm_abs /dir/. /dir/ | ||||||
| norm_abs /dir///./ /dir | norm_abs /dir///./ /dir/ | ||||||
| norm_abs /dir//sub/.. /dir | norm_abs /dir//sub/.. /dir/ | ||||||
| norm_abs /dir/sub/../ /dir | norm_abs /dir/sub/../ /dir/ | ||||||
| norm_abs //dir/sub/../. /dir | norm_abs //dir/sub/../. /dir/ | ||||||
| norm_abs /dir/s1/../s2/ /dir/s2 | norm_abs /dir/s1/../s2/ /dir/s2/ | ||||||
| norm_abs /d1/s1///s2/..//../s3/ /d1/s3 | norm_abs /d1/s1///s2/..//../s3/ /d1/s3/ | ||||||
| norm_abs /d1/s1//../s2/../../d2 /d2 | norm_abs /d1/s1//../s2/../../d2 /d2 | ||||||
| norm_abs /d1/.../d2 /d1/.../d2 | norm_abs /d1/.../d2 /d1/.../d2 | ||||||
| norm_abs /d1/..././../d2 /d1/d2 | norm_abs /d1/..././../d2 /d1/d2 | ||||||
|  |  | ||||||
|  | @ -2,10 +2,11 @@ | ||||||
|  |  | ||||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||||
| { | { | ||||||
| 	if (argc == 3 && !strcmp(argv[1], "normalize_absolute_path")) { | 	if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) { | ||||||
| 		char *buf = xmalloc(PATH_MAX + 1); | 		char *buf = xmalloc(PATH_MAX + 1); | ||||||
| 		int rv = normalize_absolute_path(buf, argv[2]); | 		int rv = normalize_path_copy(buf, argv[2]); | ||||||
| 		assert(strlen(buf) == rv); | 		if (rv) | ||||||
|  | 			buf = "++failed++"; | ||||||
| 		puts(buf); | 		puts(buf); | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Johannes Sixt
						Johannes Sixt