Skip to content

Commit f42302b

Browse files
j6tgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 43a7ddb commit f42302b

File tree

3 files changed

+26
-30
lines changed

3 files changed

+26
-30
lines changed

path.c

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -484,18 +484,12 @@ int normalize_path_copy(char *dst, const char *src)
484484
* dst0..dst is prefix portion, and dst[-1] is '/';
485485
* go up one level.
486486
*/
487-
dst -= 2; /* go past trailing '/' if any */
488-
if (dst < dst0)
487+
dst--; /* go to trailing '/' */
488+
if (dst <= dst0)
489489
return -1;
490-
while (1) {
491-
if (dst <= dst0)
492-
break;
493-
c = *dst--;
494-
if (c == '/') { /* MinGW: cannot be '\\' anymore */
495-
dst += 2;
496-
break;
497-
}
498-
}
490+
/* Windows: dst[-1] cannot be backslash anymore */
491+
while (dst0 < dst && dst[-1] != '/')
492+
dst--;
499493
}
500494
*dst = '\0';
501495
return 0;

t/t0060-path-utils.sh

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,37 @@ test_description='Test various path utilities'
88
. ./test-lib.sh
99

1010
norm_abs() {
11-
test_expect_success "normalize absolute" \
12-
"test \$(test-path-utils normalize_absolute_path '$1') = '$2'"
11+
test_expect_success "normalize absolute: $1 => $2" \
12+
"test \"\$(test-path-utils normalize_path_copy '$1')\" = '$2'"
1313
}
1414

1515
ancestor() {
16-
test_expect_success "longest ancestor" \
17-
"test \$(test-path-utils longest_ancestor_length '$1' '$2') = '$3'"
16+
test_expect_success "longest ancestor: $1 $2 => $3" \
17+
"test \"\$(test-path-utils longest_ancestor_length '$1' '$2')\" = '$3'"
1818
}
1919

20-
norm_abs "" /
20+
norm_abs "" ""
2121
norm_abs / /
2222
norm_abs // /
2323
norm_abs /// /
2424
norm_abs /. /
2525
norm_abs /./ /
26-
norm_abs /./.. /
27-
norm_abs /../. /
28-
norm_abs /./../.// /
26+
norm_abs /./.. ++failed++
27+
norm_abs /../. ++failed++
28+
norm_abs /./../.// ++failed++
2929
norm_abs /dir/.. /
3030
norm_abs /dir/sub/../.. /
31+
norm_abs /dir/sub/../../.. ++failed++
3132
norm_abs /dir /dir
32-
norm_abs /dir// /dir
33+
norm_abs /dir// /dir/
3334
norm_abs /./dir /dir
34-
norm_abs /dir/. /dir
35-
norm_abs /dir///./ /dir
36-
norm_abs /dir//sub/.. /dir
37-
norm_abs /dir/sub/../ /dir
38-
norm_abs //dir/sub/../. /dir
39-
norm_abs /dir/s1/../s2/ /dir/s2
40-
norm_abs /d1/s1///s2/..//../s3/ /d1/s3
35+
norm_abs /dir/. /dir/
36+
norm_abs /dir///./ /dir/
37+
norm_abs /dir//sub/.. /dir/
38+
norm_abs /dir/sub/../ /dir/
39+
norm_abs //dir/sub/../. /dir/
40+
norm_abs /dir/s1/../s2/ /dir/s2/
41+
norm_abs /d1/s1///s2/..//../s3/ /d1/s3/
4142
norm_abs /d1/s1//../s2/../../d2 /d2
4243
norm_abs /d1/.../d2 /d1/.../d2
4344
norm_abs /d1/..././../d2 /d1/d2

test-path-utils.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
int main(int argc, char **argv)
44
{
5-
if (argc == 3 && !strcmp(argv[1], "normalize_absolute_path")) {
5+
if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
66
char *buf = xmalloc(PATH_MAX + 1);
7-
int rv = normalize_absolute_path(buf, argv[2]);
8-
assert(strlen(buf) == rv);
7+
int rv = normalize_path_copy(buf, argv[2]);
8+
if (rv)
9+
buf = "++failed++";
910
puts(buf);
1011
return 0;
1112
}

0 commit comments

Comments
 (0)