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>
This commit is contained in:
Johannes Sixt 2009-02-07 16:08:30 +01:00 committed by Junio C Hamano
parent 43a7ddb55d
commit f42302b493
3 changed files with 26 additions and 30 deletions

16
path.c
View File

@ -484,18 +484,12 @@ int normalize_path_copy(char *dst, const char *src)
* dst0..dst is prefix portion, and dst[-1] is '/';
* go up one level.
*/
dst -= 2; /* go past trailing '/' if any */
if (dst < dst0)
return -1;
while (1) {
dst--; /* go to trailing '/' */
if (dst <= dst0)
break;
c = *dst--;
if (c == '/') { /* MinGW: cannot be '\\' anymore */
dst += 2;
break;
}
}
return -1;
/* Windows: dst[-1] cannot be backslash anymore */
while (dst0 < dst && dst[-1] != '/')
dst--;
}
*dst = '\0';
return 0;

View File

@ -8,36 +8,37 @@ test_description='Test various path utilities'
. ./test-lib.sh
norm_abs() {
test_expect_success "normalize absolute" \
"test \$(test-path-utils normalize_absolute_path '$1') = '$2'"
test_expect_success "normalize absolute: $1 => $2" \
"test \"\$(test-path-utils normalize_path_copy '$1')\" = '$2'"
}
ancestor() {
test_expect_success "longest ancestor" \
"test \$(test-path-utils longest_ancestor_length '$1' '$2') = '$3'"
test_expect_success "longest ancestor: $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 /./.. ++failed++
norm_abs /../. ++failed++
norm_abs /./../.// ++failed++
norm_abs /dir/.. /
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//sub/.. /dir
norm_abs /dir/sub/../ /dir
norm_abs //dir/sub/../. /dir
norm_abs /dir/s1/../s2/ /dir/s2
norm_abs /d1/s1///s2/..//../s3/ /d1/s3
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/s1/../s2/ /dir/s2/
norm_abs /d1/s1///s2/..//../s3/ /d1/s3/
norm_abs /d1/s1//../s2/../../d2 /d2
norm_abs /d1/.../d2 /d1/.../d2
norm_abs /d1/..././../d2 /d1/d2

View File

@ -2,10 +2,11 @@
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);
int rv = normalize_absolute_path(buf, argv[2]);
assert(strlen(buf) == rv);
int rv = normalize_path_copy(buf, argv[2]);
if (rv)
buf = "++failed++";
puts(buf);
return 0;
}