| /* |
| * dirent_uri-test.c -- test the directory entry and URI functions |
| * |
| * ==================================================================== |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * ==================================================================== |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| |
| #if defined(WIN32) || defined(__OS2__) |
| #include <direct.h> |
| #define getcwd _getcwd |
| #define getdcwd _getdcwd |
| #else |
| #include <unistd.h> /* for getcwd() */ |
| #endif |
| |
| #include <apr_general.h> |
| |
| #include "svn_pools.h" |
| #include "svn_dirent_uri.h" |
| #include "private/svn_dirent_uri_private.h" |
| #include "private/svn_fspath.h" |
| #include "private/svn_cert.h" |
| |
| #include "../svn_test.h" |
| |
| #define SVN_EMPTY_PATH "" |
| |
| /* This check must match the check on top of dirent_uri.c and path-tests.c */ |
| #if defined(WIN32) || defined(__CYGWIN__) || defined(__OS2__) |
| #define SVN_USE_DOS_PATHS |
| #endif |
| |
| #define COUNT_OF(x) (sizeof(x) / sizeof(x[0])) |
| |
| static svn_error_t * |
| test_dirent_is_root(apr_pool_t *pool) |
| { |
| apr_size_t i; |
| |
| /* Paths to test and their expected results. */ |
| struct { |
| const char *path; |
| svn_boolean_t result; |
| } tests[] = { |
| { "/", TRUE }, |
| { "/foo/bar", FALSE }, |
| { "/foo", FALSE }, |
| { "", FALSE }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:/foo", FALSE }, |
| { "X:/", TRUE }, |
| { "X:foo", FALSE }, /* Based on non absolute root */ |
| { "X:", TRUE }, |
| { "//srv/shr", TRUE }, |
| { "//srv/shr/fld", FALSE }, |
| { "//srv/s r", TRUE }, |
| { "//srv/s r/fld", FALSE }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "/", TRUE }, |
| { "/X:foo", FALSE }, |
| { "/X:", FALSE }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| svn_boolean_t retval; |
| |
| retval = svn_dirent_is_root(tests[i].path, strlen(tests[i].path)); |
| if (tests[i].result != retval) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_is_root (%s) returned %s instead of %s", |
| tests[i].path, retval ? "TRUE" : "FALSE", |
| tests[i].result ? "TRUE" : "FALSE"); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_uri_is_root(apr_pool_t *pool) |
| { |
| apr_size_t i; |
| |
| /* Paths to test and their expected results. */ |
| struct { |
| const char *path; |
| svn_boolean_t result; |
| } tests[] = { |
| { "file://", TRUE }, |
| { "file://a", FALSE }, |
| { "file:///a", FALSE }, |
| { "file:///A:", FALSE }, |
| { "http://server", TRUE }, |
| { "http://server/file", FALSE }, |
| { "http://", TRUE }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| svn_boolean_t retval; |
| |
| retval = svn_uri_is_root(tests[i].path, strlen(tests[i].path)); |
| if (tests[i].result != retval) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_is_root (%s) returned %s instead of %s", |
| tests[i].path, retval ? "TRUE" : "FALSE", |
| tests[i].result ? "TRUE" : "FALSE"); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_is_absolute(apr_pool_t *pool) |
| { |
| apr_size_t i; |
| |
| /* Paths to test and their expected results. */ |
| struct { |
| const char *path; |
| svn_boolean_t result; |
| } tests[] = { |
| { "foo/bar", FALSE }, |
| { "foo", FALSE }, |
| { "", FALSE }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "/foo/bar", FALSE }, |
| { "/foo", FALSE }, |
| { "/", FALSE }, |
| { "C:/foo", TRUE }, |
| { "C:/", TRUE }, |
| { "c:/", FALSE }, |
| { "c:/foo", FALSE }, |
| { "//srv/shr", TRUE }, |
| { "//srv/shr/fld", TRUE }, |
| { "//srv/s r", TRUE }, |
| { "//srv/s r/fld", TRUE }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "/foo/bar", TRUE }, |
| { "/foo", TRUE }, |
| { "/", TRUE }, |
| { "X:/foo", FALSE }, |
| { "X:/", FALSE }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| { "X:foo", FALSE }, /* Not special on Posix, relative on Windows */ |
| { "X:foo/bar", FALSE }, |
| { "X:", FALSE }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| svn_boolean_t retval; |
| |
| retval = svn_dirent_is_absolute(tests[i].path); |
| if (tests[i].result != retval) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_is_absolute (%s) returned %s instead of %s", |
| tests[i].path, retval ? "TRUE" : "FALSE", |
| tests[i].result ? "TRUE" : "FALSE"); |
| |
| /* Don't get absolute paths for the UNC paths, because this will |
| always fail */ |
| if (tests[i].result && |
| strncmp(tests[i].path, "//", 2) != 0) |
| { |
| const char *abspath; |
| |
| SVN_ERR(svn_dirent_get_absolute(&abspath, tests[i].path, pool)); |
| |
| if (tests[i].result != (strcmp(tests[i].path, abspath) == 0)) |
| return svn_error_createf( |
| SVN_ERR_TEST_FAILED, |
| NULL, |
| "svn_dirent_is_absolute(%s) returned TRUE, but " |
| "svn_dirent_get_absolute() returned \"%s\"", |
| tests[i].path, |
| abspath); |
| } |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_join(apr_pool_t *pool) |
| { |
| int i; |
| char *result; |
| |
| static const char * const joins[][3] = { |
| { "abc", "def", "abc/def" }, |
| { "a", "def", "a/def" }, |
| { "a", "d", "a/d" }, |
| { "/", "d", "/d" }, |
| { "/abc", "d", "/abc/d" }, |
| { "/abc", "def", "/abc/def" }, |
| { "/abc", "/def", "/def" }, |
| { "/abc", "/d", "/d" }, |
| { "/abc", "/", "/" }, |
| { "abc", "/def", "/def" }, |
| { SVN_EMPTY_PATH, "/", "/" }, |
| { "/", SVN_EMPTY_PATH, "/" }, |
| { SVN_EMPTY_PATH, "abc", "abc" }, |
| { "abc", SVN_EMPTY_PATH, "abc" }, |
| { SVN_EMPTY_PATH, "/abc", "/abc" }, |
| { SVN_EMPTY_PATH, SVN_EMPTY_PATH, SVN_EMPTY_PATH }, |
| { "/", "/", "/" }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:/", SVN_EMPTY_PATH, "X:/" }, |
| { "X:/", "abc", "X:/abc" }, |
| { "X:/", "/def", "X:/def" }, |
| { "X:/abc", "/d", "X:/d" }, |
| { "X:/abc", "/", "X:/" }, |
| { "X:/abc", "X:/", "X:/" }, |
| { "X:/abc", "X:/def", "X:/def" }, |
| { "X:", SVN_EMPTY_PATH, "X:" }, |
| { "X:", "abc", "X:abc" }, |
| { "X:", "/def", "X:/def" }, |
| { "X:abc", "/d", "X:/d" }, |
| { "X:abc", "/", "X:/" }, |
| { "X:abc", "X:/", "X:/" }, |
| { "X:abc", "X:/def", "X:/def" }, |
| { "//srv/shr", "fld", "//srv/shr/fld" }, |
| { "//srv/shr/fld", "subfld", "//srv/shr/fld/subfld" }, |
| { "//srv/shr/fld", "//srv/shr", "//srv/shr" }, |
| { "//srv/s r", "fld", "//srv/s r/fld" }, |
| { "aa", "/dir", "/dir"} , |
| { "aa", "A:", "A:" }, |
| { "aa", "A:file", "A:file"}, |
| { "A:", "/", "A:/" }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "X:abc", "X:/def", "X:abc/X:/def" }, |
| { "X:","abc", "X:/abc" }, |
| { "X:/abc", "X:/def", "X:/abc/X:/def" }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (i = 0; i < COUNT_OF(joins); i++ ) |
| { |
| const char *base = joins[i][0]; |
| const char *comp = joins[i][1]; |
| const char *expect = joins[i][2]; |
| |
| result = svn_dirent_join(base, comp, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_join(\"%s\", \"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| base, comp, result, expect); |
| |
| result = svn_dirent_join_many(pool, base, comp, SVN_VA_NULL); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_join_many(\"%s\", \"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| base, comp, result, expect); |
| } |
| |
| #define TEST_MANY(args, expect) \ |
| result = svn_dirent_join_many args ; \ |
| if (strcmp(result, expect) != 0) \ |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, \ |
| "svn_dirent_join_many" #args " returns \"%s\". " \ |
| "expected \"%s\"", \ |
| result, expect); |
| |
| TEST_MANY((pool, "abc", SVN_VA_NULL), "abc"); |
| TEST_MANY((pool, "/abc", SVN_VA_NULL), "/abc"); |
| TEST_MANY((pool, "/", SVN_VA_NULL), "/"); |
| |
| TEST_MANY((pool, "abc", "def", "ghi", SVN_VA_NULL), "abc/def/ghi"); |
| TEST_MANY((pool, "abc", "/def", "ghi", SVN_VA_NULL), "/def/ghi"); |
| TEST_MANY((pool, "/abc", "def", "ghi", SVN_VA_NULL), "/abc/def/ghi"); |
| TEST_MANY((pool, "abc", "def", "/ghi", SVN_VA_NULL), "/ghi"); |
| TEST_MANY((pool, "/", "def", "/ghi", SVN_VA_NULL), "/ghi"); |
| TEST_MANY((pool, "/", "/def", "/ghi", SVN_VA_NULL), "/ghi"); |
| |
| TEST_MANY((pool, SVN_EMPTY_PATH, "def", "ghi", SVN_VA_NULL), "def/ghi"); |
| TEST_MANY((pool, "abc", SVN_EMPTY_PATH, "ghi", SVN_VA_NULL), "abc/ghi"); |
| TEST_MANY((pool, "abc", "def", SVN_EMPTY_PATH, SVN_VA_NULL), "abc/def"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "def", SVN_EMPTY_PATH, SVN_VA_NULL), "def"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, SVN_EMPTY_PATH, "ghi", SVN_VA_NULL), "ghi"); |
| TEST_MANY((pool, "abc", SVN_EMPTY_PATH, SVN_EMPTY_PATH, SVN_VA_NULL), "abc"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "def", "/ghi", SVN_VA_NULL), "/ghi"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, SVN_EMPTY_PATH, "/ghi", SVN_VA_NULL), "/ghi"); |
| |
| TEST_MANY((pool, "/", "def", "ghi", SVN_VA_NULL), "/def/ghi"); |
| TEST_MANY((pool, "abc", "/", "ghi", SVN_VA_NULL), "/ghi"); |
| TEST_MANY((pool, "abc", "def", "/", SVN_VA_NULL), "/"); |
| TEST_MANY((pool, "/", "/", "ghi", SVN_VA_NULL), "/ghi"); |
| TEST_MANY((pool, "/", "/", "/", SVN_VA_NULL), "/"); |
| TEST_MANY((pool, "/", SVN_EMPTY_PATH, "ghi", SVN_VA_NULL), "/ghi"); |
| TEST_MANY((pool, "/", "def", SVN_EMPTY_PATH, SVN_VA_NULL), "/def"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "/", "ghi", SVN_VA_NULL), "/ghi"); |
| TEST_MANY((pool, "/", SVN_EMPTY_PATH, SVN_EMPTY_PATH, SVN_VA_NULL), "/"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "/", SVN_EMPTY_PATH, SVN_VA_NULL), "/"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, SVN_EMPTY_PATH, "/", SVN_VA_NULL), "/"); |
| |
| #ifdef SVN_USE_DOS_PATHS |
| TEST_MANY((pool, "X:/", "def", "ghi", SVN_VA_NULL), "X:/def/ghi"); |
| TEST_MANY((pool, "abc", "X:/", "ghi", SVN_VA_NULL), "X:/ghi"); |
| TEST_MANY((pool, "abc", "def", "X:/", SVN_VA_NULL), "X:/"); |
| TEST_MANY((pool, "X:/", "X:/", "ghi", SVN_VA_NULL), "X:/ghi"); |
| TEST_MANY((pool, "X:/", "X:/", "/", SVN_VA_NULL), "/"); |
| TEST_MANY((pool, "X:/", SVN_EMPTY_PATH, "ghi", SVN_VA_NULL), "X:/ghi"); |
| TEST_MANY((pool, "X:/", "def", SVN_EMPTY_PATH, SVN_VA_NULL), "X:/def"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "X:/", "ghi", SVN_VA_NULL), "X:/ghi"); |
| TEST_MANY((pool, "X:/", SVN_EMPTY_PATH, SVN_EMPTY_PATH, SVN_VA_NULL), "X:/"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "X:/", SVN_EMPTY_PATH, SVN_VA_NULL), "X:/"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, SVN_EMPTY_PATH, "X:/", SVN_VA_NULL), "X:/"); |
| |
| TEST_MANY((pool, "X:", "def", "ghi", SVN_VA_NULL), "X:def/ghi"); |
| TEST_MANY((pool, "X:", "X:/", "ghi", SVN_VA_NULL), "X:/ghi"); |
| TEST_MANY((pool, "X:", "X:/", "/", SVN_VA_NULL), "/"); |
| TEST_MANY((pool, "X:", SVN_EMPTY_PATH, "ghi", SVN_VA_NULL), "X:ghi"); |
| TEST_MANY((pool, "X:", "def", SVN_EMPTY_PATH, SVN_VA_NULL), "X:def"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "X:", "ghi", SVN_VA_NULL), "X:ghi"); |
| TEST_MANY((pool, "//srv/shr", "def", "ghi", SVN_VA_NULL), "//srv/shr/def/ghi"); |
| TEST_MANY((pool, "//srv/shr/fld", "def", "ghi", SVN_VA_NULL), "//srv/shr/fld/def/ghi"); |
| TEST_MANY((pool, "//srv/shr/fld", "def", "//srv/shr", SVN_VA_NULL), "//srv/shr"); |
| TEST_MANY((pool, "//srv/s r/fld", "def", "//srv/s r", SVN_VA_NULL), "//srv/s r"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "//srv/shr/fld", "def", "ghi", SVN_VA_NULL), "//srv/shr/fld/def/ghi"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "//srv/shr/fld", "def", "//srv/shr", SVN_VA_NULL), "//srv/shr"); |
| |
| TEST_MANY((pool, "abcd", "/dir", "A:", "file", SVN_VA_NULL), "A:file"); |
| TEST_MANY((pool, "abcd", "A:", "/dir", "file", SVN_VA_NULL), "A:/dir/file"); |
| |
| #else /* !SVN_USE_DOS_PATHS */ |
| TEST_MANY((pool, "X:", "def", "ghi", SVN_VA_NULL), "X:/def/ghi"); |
| TEST_MANY((pool, "X:", SVN_EMPTY_PATH, "ghi", SVN_VA_NULL), "X:/ghi"); |
| TEST_MANY((pool, "X:", "def", SVN_EMPTY_PATH, SVN_VA_NULL), "X:/def"); |
| TEST_MANY((pool, SVN_EMPTY_PATH, "X:", "ghi", SVN_VA_NULL), "X:/ghi"); |
| #endif /* SVN_USE_DOS_PATHS */ |
| |
| /* ### probably need quite a few more tests... */ |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_join(apr_pool_t *pool) |
| { |
| int i; |
| char *result; |
| |
| static const char * const joins[][3] = { |
| { "abc", "def", "abc/def" }, |
| { "a", "def", "a/def" }, |
| { "a", "d", "a/d" }, |
| { SVN_EMPTY_PATH, "abc", "abc" }, |
| { "abc", SVN_EMPTY_PATH, "abc" }, |
| { "", "", "" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(joins); i++) |
| { |
| const char *base = joins[i][0]; |
| const char *comp = joins[i][1]; |
| const char *expect = joins[i][2]; |
| |
| result = svn_relpath_join(base, comp, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_join(\"%s\", \"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| base, comp, result, expect); |
| |
| /*result = svn_relpath_join_many(pool, base, comp, NULL); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_join_many(\"%s\", \"%s\") " |
| "returned \"%s\". expected \"%s\"", |
| base, comp, result, expect);*/ |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_basename(apr_pool_t *pool) |
| { |
| int i; |
| const char *result; |
| |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "abc", "abc" }, |
| { "/abc", "abc" }, |
| { "/abc", "abc" }, |
| { "/x/abc", "abc" }, |
| { "/xx/abc", "abc" }, |
| { "/xx/abc", "abc" }, |
| { "/xx/abc", "abc" }, |
| { "a", "a" }, |
| { "/a", "a" }, |
| { "/b/a", "a" }, |
| { "/b/a", "a" }, |
| { "/", "" }, |
| { SVN_EMPTY_PATH, SVN_EMPTY_PATH }, |
| { "X:/abc", "abc" }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:", "" }, |
| { "X:/", "" }, |
| { "X:abc", "abc" }, |
| { "//srv/shr", "" }, |
| { "//srv/shr/fld", "fld" }, |
| { "//srv/shr/fld/subfld", "subfld" }, |
| { "//srv/s r/fld", "fld" }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "X:", "X:" }, |
| { "X:abc", "X:abc" }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *path = tests[i].path; |
| const char *expect = tests[i].result; |
| |
| result = svn_dirent_basename(path, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_basename(\"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| path, result, expect); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_basename(apr_pool_t *pool) |
| { |
| int i; |
| const char *result; |
| |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "", "" }, |
| { " ", " " }, |
| { "foo/bar", "bar" }, |
| { "foo/bar/bad", "bad" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *path = tests[i].path; |
| const char *expect = tests[i].result; |
| |
| result = svn_relpath_basename(path, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_basename(\"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| path, result, expect); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_uri_basename(apr_pool_t *pool) |
| { |
| int i; |
| const char *result; |
| |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "http://s/file", "file" }, |
| { "http://s/dir/file", "file" }, |
| { "http://s/some%20dir/other%20file", "other file" }, |
| { "http://s", "" }, |
| { "file://", "" }, |
| { "file:///a", "a" }, |
| { "file:///a/b", "b" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *path = tests[i].path; |
| const char *expect = tests[i].result; |
| |
| result = svn_uri_basename(path, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_basename(\"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| path, result, expect); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_dirname(apr_pool_t *pool) |
| { |
| int i; |
| char *result; |
| |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "abc", "" }, |
| { "/abc", "/" }, |
| { "/x/abc", "/x" }, |
| { "/xx/abc", "/xx" }, |
| { "a", "" }, |
| { "/a", "/" }, |
| { "/b/a", "/b" }, |
| { "/", "/" }, |
| { SVN_EMPTY_PATH, SVN_EMPTY_PATH }, |
| { "X:abc/def", "X:abc" }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:/", "X:/" }, |
| { "X:/abc", "X:/" }, |
| { "X:abc", "X:" }, |
| { "X:", "X:" }, |
| { "//srv/shr", "//srv/shr" }, |
| { "//srv/shr/fld", "//srv/shr" }, |
| { "//srv/shr/fld/subfld", "//srv/shr/fld" }, |
| { "//srv/s r/fld", "//srv/s r" }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| /* on non-Windows platforms, ':' is allowed in pathnames */ |
| { "X:", "" }, |
| { "X:abc", "" }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *path = tests[i].path; |
| const char *expect = tests[i].result; |
| |
| result = svn_dirent_dirname(path, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_dirname(\"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| path, result, expect); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_dirname(apr_pool_t *pool) |
| { |
| int i; |
| char *result; |
| |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "", "" }, |
| { " ", "" }, |
| { "foo", "" }, |
| { "foo/bar", "foo" }, |
| { "foo/bar/bad", "foo/bar" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *path = tests[i].path; |
| const char *expect = tests[i].result; |
| |
| result = svn_relpath_dirname(path, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_dirname(\"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| path, result, expect); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_uri_dirname(apr_pool_t *pool) |
| { |
| int i; |
| char *result; |
| |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "http://server/dir", "http://server" }, |
| { "http://server/dir/file", "http://server/dir" }, |
| { "http://server", "http://server" }, |
| { "file:///a/b", "file:///a" }, |
| { "file:///a", "file://" }, |
| { "file://", "file://" }, |
| #ifdef WIN32 |
| { "file:///A:/dir", "file:///A:" }, |
| { "file:///A:", "file://" }, |
| #endif |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *path = tests[i].path; |
| const char *expect = tests[i].result; |
| |
| result = svn_uri_dirname(path, pool); |
| if (strcmp(result, expect)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_dirname(\"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| path, result, expect); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| /* Paths to test and the expected result, for canonicalize tests. */ |
| typedef struct testcase_canonicalize_t { |
| const char *path; |
| const char *result; |
| } testcase_canonicalize_t; |
| |
| static svn_error_t * |
| test_dirent_canonicalize(apr_pool_t *pool) |
| { |
| const testcase_canonicalize_t *t; |
| static const testcase_canonicalize_t tests[] = { |
| { "", "" }, |
| { ".", "" }, |
| { "/", "/" }, |
| { "/.", "/" }, |
| { "./", "" }, |
| { "./.", "" }, |
| { "//", "/" }, |
| { "/////", "/" }, |
| { "./././.", "" }, |
| { "////././.", "/" }, |
| { "foo", "foo" }, |
| { ".foo", ".foo" }, |
| { "foo.", "foo." }, |
| { "/foo", "/foo" }, |
| { "foo/", "foo" }, |
| { "foo./", "foo." }, |
| { "foo./.", "foo." }, |
| { "foo././/.", "foo." }, |
| { "/foo/bar", "/foo/bar" }, |
| { "foo/..", "foo/.." }, |
| { "foo/../", "foo/.." }, |
| { "foo/../.", "foo/.." }, |
| { "foo//.//bar", "foo/bar" }, |
| { "//foo", "/foo" }, |
| { "///foo", "/foo" }, |
| { "/.//./.foo", "/.foo" }, |
| { ".///.foo", ".foo" }, |
| { "../foo", "../foo" }, |
| { "../../foo/", "../../foo" }, |
| { "../../foo/..", "../../foo/.." }, |
| { "/../../", "/../.." }, |
| { "X:/foo", "X:/foo" }, |
| { "X:", "X:" }, |
| { "X:foo", "X:foo" }, |
| { "C:/folder/subfolder/file", "C:/folder/subfolder/file" }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:/", "X:/" }, |
| { "X:/./", "X:/" }, |
| { "x:/", "X:/" }, |
| { "x:", "X:" }, |
| { "x:AAAAA", "X:AAAAA" }, |
| /* We permit UNC dirents on Windows. By definition UNC |
| * dirents must have two components so we should remove the |
| * double slash if there is only one component. */ |
| { "//hst/foo", "//hst/foo" }, |
| { "//hst", "/hst" }, |
| { "//hst/./", "/hst" }, |
| { "//server/share/", "//server/share" }, |
| { "//server/SHare/", "//server/SHare" }, |
| { "//SERVER/SHare/", "//server/SHare" }, |
| { "//srv/s r", "//srv/s r" }, |
| { "//srv/s r/qq", "//srv/s r/qq" }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| const char *canonical = svn_dirent_canonicalize(t->path, pool); |
| |
| if (strcmp(canonical, t->result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_canonicalize(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| t->path, canonical, t->result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_canonicalize(apr_pool_t *pool) |
| { |
| const testcase_canonicalize_t *t; |
| static const testcase_canonicalize_t tests[] = { |
| { "", "" }, |
| { ".", "" }, |
| { "/", "" }, |
| { "/.", "" }, |
| { "./", "" }, |
| { "./.", "" }, |
| { "//", "" }, |
| { "/////", "" }, |
| { "./././.", "" }, |
| { "////././.", "" }, |
| { "foo", "foo" }, |
| { ".foo", ".foo" }, |
| { "foo.", "foo." }, |
| { "/foo", "foo" }, |
| { "foo/", "foo" }, |
| { "foo./", "foo." }, |
| { "foo./.", "foo." }, |
| { "foo././/.", "foo." }, |
| { "/foo/bar", "foo/bar" }, |
| { "foo/..", "foo/.." }, |
| { "foo/../", "foo/.." }, |
| { "foo/../.", "foo/.." }, |
| { "foo//.//bar", "foo/bar" }, |
| { "//foo", "foo" }, |
| { "///foo", "foo" }, |
| { "/.//./.foo", ".foo" }, |
| { ".///.foo", ".foo" }, |
| { "../foo", "../foo" }, |
| { "../../foo/", "../../foo" }, |
| { "../../foo/..", "../../foo/.." }, |
| { "/../../", "../.." }, |
| { "X:/foo", "X:/foo" }, |
| { "X:", "X:" }, |
| { "X:foo", "X:foo" }, |
| { "C:/folder/subfolder/file", "C:/folder/subfolder/file" }, |
| { "http://hst", "http:/hst" }, |
| { "http://hst/foo/../bar","http:/hst/foo/../bar" }, |
| { "http://hst/", "http:/hst" }, |
| { "http:///", "http:" }, |
| { "https://", "https:" }, |
| { "file:///", "file:" }, |
| { "file://", "file:" }, |
| { "svn:///", "svn:" }, |
| { "svn+ssh:///", "svn+ssh:" }, |
| { "http://HST/", "http:/HST" }, |
| { "http://HST/FOO/BaR", "http:/HST/FOO/BaR" }, |
| { "svn+ssh://j.raNDom@HST/BaR", "svn+ssh:/j.raNDom@HST/BaR" }, |
| { "svn+SSH://j.random:jRaY@HST/BaR", "svn+SSH:/j.random:jRaY@HST/BaR" }, |
| { "SVN+ssh://j.raNDom:jray@HST/BaR", "SVN+ssh:/j.raNDom:jray@HST/BaR" }, |
| { "fILe:///Users/jrandom/wc", "fILe:/Users/jrandom/wc" }, |
| { "fiLE:///", "fiLE:" }, |
| { "fiLE://", "fiLE:" }, |
| { "file://SRV/shr/repos", "file:/SRV/shr/repos" }, |
| { "file://SRV/SHR/REPOS", "file:/SRV/SHR/REPOS" }, |
| { "http://server////", "http:/server" }, |
| { "http://server/file//", "http:/server/file" }, |
| { "http://server//.//f//", "http:/server/f" }, |
| { "file:///c:/temp/repos", "file:/c:/temp/repos" }, |
| { "file:///c:/temp/REPOS", "file:/c:/temp/REPOS" }, |
| { "file:///C:/temp/REPOS", "file:/C:/temp/REPOS" }, |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| const char *canonical = svn_relpath_canonicalize(t->path, pool); |
| |
| if (strcmp(canonical, t->result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_canonicalize(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| t->path, canonical, t->result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static const testcase_canonicalize_t uri_canonical_tests[] = |
| { |
| { "http://hst", "http://hst" }, |
| { "http://hst/foo/../bar","http://hst/foo/../bar" }, |
| { "http://hst/", "http://hst" }, |
| { "http:///", "http://" }, |
| { "http:///example.com/", "http:///example.com" }, |
| { "http:////example.com/", "http:///example.com" }, |
| { "http://///////example.com/", "http:///example.com" }, |
| { "https://", "https://" }, |
| { "file:///", "file://" }, |
| { "file://", "file://" }, |
| { "svn:///", "svn://" }, |
| { "svn+ssh:///", "svn+ssh://" }, |
| { "http://HST/", "http://hst" }, |
| { "http://HST/FOO/BaR", "http://hst/FOO/BaR" }, |
| { "svn+ssh://jens@10.0.1.1", "svn+ssh://jens@10.0.1.1" }, |
| { "svn+ssh://j.raNDom@HST/BaR", "svn+ssh://j.raNDom@hst/BaR" }, |
| { "svn+SSH://j.random:jRaY@HST/BaR", "svn+ssh://j.random:jRaY@hst/BaR" }, |
| { "SVN+ssh://j.raNDom:jray@HST/BaR", "svn+ssh://j.raNDom:jray@hst/BaR" }, |
| { "svn+ssh://j.raNDom:jray@hst/BaR", "svn+ssh://j.raNDom:jray@hst/BaR" }, |
| { "fILe:///Users/jrandom/wc", "file:///Users/jrandom/wc" }, |
| { "fiLE:///", "file://" }, |
| { "fiLE://", "file://" }, |
| { "file://SRV/shr/repos", "file://srv/shr/repos" }, |
| { "file://SRV/SHR/REPOS", "file://srv/SHR/REPOS" }, |
| { "http://server////", "http://server" }, |
| { "http://server/file//", "http://server/file" }, |
| { "http://server//.//f//", "http://server/f" }, |
| { "http://server/d/.", "http://server/d" }, |
| { "http://server/d/%2E", "http://server/d" }, |
| { "http://server/d/./q", "http://server/d/q" }, |
| { "http://server/d/%2E/q", "http://server/d/q" }, |
| { "http://server/%", "http://server/%25" }, |
| { "http://server/%25", "http://server/%25" }, |
| { "http://server/%/d", "http://server/%25/d" }, |
| { "http://server/%25/d", "http://server/%25/d" }, |
| { "http://server/+", "http://server/+" }, |
| { "http://server/%2B", "http://server/+" }, |
| { "http://server/ ", "http://server/%20" }, |
| { "http://server/#", "http://server/%23" }, |
| { "http://server/d/a%2Fb", "http://server/d/a/b" }, |
| { "http://server/d/.%2F.", "http://server/d" }, |
| { "http://server/d/%2E%2F%2E", "http://server/d" }, |
| { "file:///C%3a/temp", "file:///C:/temp" }, |
| { "http://server/cr%AB", "http://server/cr%AB" }, |
| { "http://server/cr%ab", "http://server/cr%AB" }, |
| { "http://hst/foo/bar/", "http://hst/foo/bar" }, |
| { "http://hst/foo/.", "http://hst/foo" }, |
| { "http://hst/foo/%2E", "http://hst/foo" }, |
| { "http://hst/%", "http://hst/%25" }, |
| { "http://hst/+", "http://hst/+" }, |
| { "http://hst/#", "http://hst/%23" }, |
| { "http://hst/ ", "http://hst/%20" }, |
| { "http://hst/%2B", "http://hst/+" }, |
| { "http://HST", "http://hst" }, |
| { "http://hst/foo/./bar", "http://hst/foo/bar" }, |
| { "hTTp://hst/foo/bar", "http://hst/foo/bar" }, |
| { "http://hst/foo/bar/", "http://hst/foo/bar" }, |
| { "file://SRV/share/repo", "file://srv/share/repo" }, |
| { "file://srv/SHARE/repo", "file://srv/SHARE/repo" }, |
| { "file://srv/share/repo", "file://srv/share/repo" }, |
| { "file://srv/share/repo/","file://srv/share/repo" }, |
| { "file:///folder/c#", "file:///folder/c%23" }, /* # needs escaping */ |
| { "file:///fld/with space","file:///fld/with%20space" }, /* # needs escaping */ |
| { "file:///fld/c%23", "file:///fld/c%23" }, /* Properly escaped C# */ |
| { "file:///%DE%AD%BE%EF", "file:///%DE%AD%BE%EF" }, |
| { "file:///%de%ad%be%ef", "file:///%DE%AD%BE%EF" }, |
| { "file:///%DE%ad%BE%ef", "file:///%DE%AD%BE%EF" }, |
| /* With default port number; these are non-canonical */ |
| { "http://server:", "http://server" }, |
| { "http://server:/", "http://server" }, |
| { "http://server:80", "http://server" }, |
| { "http://SERVER:80", "http://server" }, |
| { "http://server:80/", "http://server" }, |
| { "http://server:80/p", "http://server/p" }, |
| { "https://server:", "https://server" }, |
| { "https://Server:443/q", "https://server/q" }, |
| { "svn://server:3690/", "svn://server" }, |
| { "svn://sERVER:3690/r", "svn://server/r" }, |
| { "svn://server:/r", "svn://server/r" }, |
| /* With non-default port number; both canonical and non-c. examples */ |
| { "http://server:1", "http://server:1" }, |
| { "http://server:443", "http://server:443" }, |
| { "http://server:81/", "http://server:81" }, |
| { "http://SERVER:3690/", "http://server:3690" }, |
| { "https://server:3690", "https://server:3690" }, |
| { "https://SERVER:80/", "https://server:80" }, |
| { "svn://server:80", "svn://server:80" }, |
| { "svn://SERVER:443/", "svn://server:443" }, |
| { "file:///C%7C/temp/REPOS", "file:///C%7C/temp/REPOS" }, |
| { "file:///C|/temp/REPOS", "file:///C%7C/temp/REPOS" }, |
| { "file:///C:/", "file:///C:" }, |
| { "http://[::1]/", "http://[::1]" }, |
| { "http://[::1]:80/", "http://[::1]" }, |
| { "https://[::1]:443", "https://[::1]" }, |
| { "http://[::1]/", "http://[::1]" }, |
| { "http://[::1]:80/", "http://[::1]" }, |
| { "https://[::1]:443", "https://[::1]" }, |
| { "http://[FACE:B00C::]/s","http://[face:b00c::]/s" }, |
| { "svn+ssh://b@[1:2::3]/s","svn+ssh://b@[1:2::3]/s" }, |
| { "file:///A%2f%2Fb%2fc", "file:///A/b/c"}, |
| { "file:///A%2fb%2f%2Fc", "file:///A/b/c"}, |
| #ifdef SVN_USE_DOS_PATHS |
| { "file:///c:/temp/repos", "file:///C:/temp/repos" }, |
| { "file:///c:/temp/REPOS", "file:///C:/temp/REPOS" }, |
| { "file:///C:/temp/REPOS", "file:///C:/temp/REPOS" }, |
| { "file:///c:/", "file:///C:" }, |
| { "file:///c:%2ftemp", "file:///C:/temp"}, |
| { "file:///C:hi", "file:///C:hi" }, |
| { "file:///c:hi", "file:///C:hi" }, |
| { "file:///C:hi/Q", "file:///C:hi/Q" }, |
| { "file:///c:hi/q", "file:///C:hi/q" }, |
| { "file:///c:hi%2fD", "file:///C:hi/D" }, |
| { "file:///c:hi%25/A", "file:///C:hi%25/A"}, |
| { "file:///c:hi%2E/A", "file:///C:hi./A"}, |
| { "file:///c:hi%/A", "file:///C:hi%25/A"}, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "file:///c:/temp/repos", "file:///c:/temp/repos" }, |
| { "file:///c:/temp/REPOS", "file:///c:/temp/REPOS" }, |
| { "file:///C:/temp/REPOS", "file:///C:/temp/REPOS" }, |
| { "file:///c:/", "file:///c:" }, |
| { "file:///c:%2ftemp", "file:///c:/temp"}, |
| { "file:///C:hi", "file:///C:hi" }, |
| { "file:///c:hi", "file:///c:hi" }, |
| { "file:///C:hi/Q", "file:///C:hi/Q" }, |
| { "file:///c:hi/q", "file:///c:hi/q" }, |
| { "file:///c:hi%2fD", "file:///c:hi/D" }, |
| { "file:///c:hi%25/A", "file:///c:hi%25/A" }, |
| { "file:///c:hi%2E/A", "file:///c:hi./A"}, |
| { "file:///c:hi%/A", "file:///c:hi%25/A"}, |
| #endif /* SVN_USE_DOS_PATHS */ |
| /* Hostnames that look like non-canonical paths */ |
| { "file://./foo", "file://./foo" }, |
| { "http://./foo", "http://./foo" }, |
| /* Some invalid URLs, these still have a canonical form */ |
| { "http://server:81:81/", "http://server:81:81" }, |
| { "http://server:81foo/", "http://server:81foo" }, |
| { "http://server::/", "http://server::" }, |
| { "http://server:-/", "http://server:-" }, |
| { "http://hst:1.2.3.4.5/", "http://hst:1.2.3.4.5"}, |
| { "http://hst:1.2.999.4/", "http://hst:1.2.999.4"}, |
| /* svn_uri_is_canonical() was a private function in the 1.6 API, and |
| has since taken a MAJOR change of direction, namely that only |
| absolute URLs are considered canonical uris now. */ |
| { "", NULL }, |
| { ".", NULL }, |
| { "/", NULL }, |
| { "/.", NULL }, |
| { "./", NULL }, |
| { "./.", NULL }, |
| { "//", NULL }, |
| { "/////", NULL }, |
| { "./././.", NULL }, |
| { "////././.", NULL }, |
| { "foo", NULL }, |
| { ".foo", NULL }, |
| { "foo.", NULL }, |
| { "/foo", NULL }, |
| { "foo/", NULL }, |
| { "foo./", NULL }, |
| { "foo./.", NULL }, |
| { "foo././/.", NULL }, |
| { "/foo/bar", NULL }, |
| { "foo/..", NULL }, |
| { "foo/../", NULL }, |
| { "foo/../.", NULL }, |
| { "foo//.//bar", NULL }, |
| { "//foo", NULL }, |
| { "///foo", NULL }, |
| { "/.//./.foo", NULL }, |
| { ".///.foo", NULL }, |
| { "../foo", NULL }, |
| { "../../foo/", NULL }, |
| { "../../foo/..", NULL }, |
| { "/../../", NULL }, |
| { "dirA", NULL }, |
| { "foo/dirA", NULL }, |
| { "foo/./bar", NULL }, |
| { "C:/folder/subfolder/file", NULL }, |
| { "X:/foo", NULL }, |
| { "X:", NULL }, |
| { "X:foo", NULL }, |
| { "X:foo/", NULL }, |
| /* Some people use colons in their filenames. */ |
| { ":", NULL }, |
| { ".:", NULL }, |
| { "foo/.:", NULL }, |
| { "//server/share", NULL }, /* Only valid as dirent */ |
| { "//server", NULL }, |
| { "//", NULL }, |
| { "sch://@/", NULL }, |
| { "sch:///", NULL }, |
| { "svn://:", NULL }, |
| }; |
| |
| static svn_error_t * |
| test_uri_canonicalize(apr_pool_t *pool) |
| { |
| const testcase_canonicalize_t *t; |
| |
| for (t = uri_canonical_tests; |
| t < uri_canonical_tests + COUNT_OF(uri_canonical_tests); |
| t++) |
| { |
| const char *canonical; |
| |
| if (! t->result) |
| continue; |
| |
| canonical = svn_uri_canonicalize(t->path, pool); |
| |
| if (strcmp(canonical, t->result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_canonicalize(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| t->path, canonical, t->result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| /* Paths to test and the expected result, for is_canonical tests. */ |
| typedef struct testcase_is_canonical_t { |
| const char *path; |
| svn_boolean_t canonical; |
| } testcase_is_canonical_t; |
| |
| static svn_error_t * |
| test_dirent_is_canonical(apr_pool_t *pool) |
| { |
| const testcase_is_canonical_t *t; |
| static const testcase_is_canonical_t tests[] = { |
| { "", TRUE }, |
| { ".", FALSE }, |
| { "/", TRUE }, |
| { "/.", FALSE }, |
| { "./", FALSE }, |
| { "./.", FALSE }, |
| { "//", FALSE }, |
| { "/////", FALSE }, |
| { "./././.", FALSE }, |
| { "////././.", FALSE }, |
| { "foo", TRUE }, |
| { ".foo", TRUE }, |
| { "foo.", TRUE }, |
| { "/foo", TRUE }, |
| { "foo/", FALSE }, |
| { "foo./", FALSE }, |
| { "foo./.", FALSE }, |
| { "foo././/.", FALSE }, |
| { "/foo/bar", TRUE }, |
| { "foo/..", TRUE }, |
| { "foo/../", FALSE }, |
| { "foo/../.", FALSE }, |
| { "foo//.//bar", FALSE }, |
| { "//foo", FALSE }, |
| { "///foo", FALSE }, |
| { "/.//./.foo", FALSE }, |
| { ".///.foo", FALSE }, |
| { "../foo", TRUE }, |
| { "../../foo/", FALSE }, |
| { "../../foo/..", TRUE }, |
| { "/../../", FALSE }, |
| { "dirA", TRUE }, |
| { "foo/dirA", TRUE }, |
| { "foo/./bar", FALSE }, |
| { "C:/folder/subfolder/file", TRUE }, |
| { "X:/foo", TRUE }, |
| { "X:", TRUE }, |
| { "X:foo", TRUE }, |
| { "X:foo/", FALSE }, |
| { "file with spaces", TRUE }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:/", TRUE }, |
| { "X:/foo", TRUE }, |
| { "X:", TRUE }, |
| { "X:foo", TRUE }, |
| { "x:/", FALSE }, |
| { "x:/foo", FALSE }, |
| { "x:", FALSE }, |
| { "x:foo", FALSE }, |
| /* We permit UNC dirents on Windows. By definition UNC |
| * dirents must have two components so we should remove the |
| * double slash if there is only one component. */ |
| { "//hst", FALSE }, |
| { "//hst/./", FALSE }, |
| { "//server/share/", FALSE }, |
| { "//server/share", TRUE }, |
| { "//server/SHare", TRUE }, |
| { "//SERVER/SHare", FALSE }, |
| { "//srv/SH RE", TRUE }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "X:/", FALSE }, |
| /* Some people use colons in their filenames. */ |
| { ":", TRUE }, |
| { ".:", TRUE }, |
| { "foo/.:", TRUE }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| svn_boolean_t canonical; |
| const char* canonicalized; |
| |
| canonical = svn_dirent_is_canonical(t->path, pool); |
| if (t->canonical != canonical) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_is_canonical(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| t->path, |
| canonical ? "TRUE" : "FALSE", |
| t->canonical ? "TRUE" : "FALSE"); |
| |
| canonicalized = svn_dirent_canonicalize(t->path, pool); |
| |
| if ((canonical && strcmp(t->path, canonicalized) != 0) |
| || (!canonical && strcmp(t->path, canonicalized) == 0)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_canonicalize(\"%s\") returned \"%s\" " |
| "while svn_dirent_is_canonical returned TRUE", |
| t->path, |
| canonicalized); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_is_canonical(apr_pool_t *pool) |
| { |
| const testcase_is_canonical_t *t; |
| static const testcase_is_canonical_t tests[] = { |
| { "", TRUE }, |
| { ".", FALSE }, |
| { "..", TRUE }, |
| { "/", FALSE }, |
| { "/.", FALSE }, |
| { "./", FALSE }, |
| { "./.", FALSE }, |
| { "//", FALSE }, |
| { "/////", FALSE }, |
| { "./././.", FALSE }, |
| { "////././.", FALSE }, |
| { "foo", TRUE }, |
| { ".foo", TRUE }, |
| { "foo.", TRUE }, |
| { "/foo", FALSE }, |
| { "foo/", FALSE }, |
| { "foo./", FALSE }, |
| { "foo./.", FALSE }, |
| { "foo././/.", FALSE }, |
| { "/foo/bar", FALSE }, |
| { "foo/..", TRUE }, |
| { "foo/../", FALSE }, |
| { "foo/../.", FALSE }, |
| { "foo//.//bar", FALSE }, |
| { "//foo", FALSE }, |
| { "///foo", FALSE }, |
| { "/.//./.foo", FALSE }, |
| { ".///.foo", FALSE }, |
| { "../foo", TRUE }, |
| { "../../foo/", FALSE }, |
| { "../../foo/..", TRUE }, |
| { "/../../", FALSE }, |
| { "dirA", TRUE }, |
| { "foo/dirA", TRUE }, |
| { "foo/./bar", FALSE }, |
| { "http://hst", FALSE }, |
| { "http://hst/foo/../bar", FALSE }, |
| { "http://HST/", FALSE }, |
| { "http://HST/FOO/BaR", FALSE }, |
| { "svn+ssh://jens@10.0.1.1", FALSE }, |
| { "svn+ssh:/jens@10.0.1.1", TRUE }, |
| { "fILe:///Users/jrandom/wc", FALSE }, |
| { "fILe:/Users/jrandom/wc", TRUE }, |
| { "X:/foo", TRUE }, |
| { "X:", TRUE }, |
| { "X:foo", TRUE }, |
| { "X:foo/", FALSE }, |
| /* Some people use colons in their filenames. */ |
| { ":", TRUE }, |
| { ".:", TRUE }, |
| { "foo/.:", TRUE }, |
| { "//server/share", FALSE }, /* Only valid as dirent */ |
| { "//server", FALSE }, |
| { "//", FALSE }, |
| { "file:///c:/temp/repos", FALSE }, |
| { "file:///c:/temp/REPOS", FALSE }, |
| { "file:///C:/temp/REPOS", FALSE }, |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| svn_boolean_t canonical; |
| const char* canonicalized; |
| |
| canonical = svn_relpath_is_canonical(t->path); |
| if (t->canonical != canonical) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_is_canonical(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| t->path, |
| canonical ? "TRUE" : "FALSE", |
| t->canonical ? "TRUE" : "FALSE"); |
| |
| canonicalized = svn_relpath_canonicalize(t->path, pool); |
| |
| if ((canonical && strcmp(t->path, canonicalized) != 0) |
| || (!canonical && strcmp(t->path, canonicalized) == 0)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_canonicalize(\"%s\") returned " |
| "\"%s\" while svn_relpath_is_canonical " |
| "returned %s", |
| t->path, |
| canonicalized, |
| canonical ? "TRUE" : "FALSE"); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_uri_is_canonical(apr_pool_t *pool) |
| { |
| const testcase_canonicalize_t *t; |
| |
| for (t = uri_canonical_tests; |
| t < uri_canonical_tests + COUNT_OF(uri_canonical_tests); |
| t++) |
| { |
| svn_boolean_t canonical; |
| |
| canonical = svn_uri_is_canonical(t->path, pool); |
| if (canonical != (t->result && strcmp(t->path, t->result) == 0)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_is_canonical(\"%s\") returned " |
| "\"%s\"; canonical form is \"%s\"", |
| t->path, |
| canonical ? "TRUE" : "FALSE", |
| t->result); |
| |
| if (t->result && !svn_uri_is_canonical(t->result, pool)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_is_canonical(\"%s\") returned " |
| "FALSE on canonical form", |
| t->result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_split(apr_pool_t *pool) |
| { |
| apr_size_t i; |
| |
| static const char * const paths[][3] = { |
| { "/foo/bar", "/foo", "bar" }, |
| { "/foo/bar/ ", "/foo/bar", " " }, |
| { "/foo", "/", "foo" }, |
| { "foo", SVN_EMPTY_PATH, "foo" }, |
| { ".bar", SVN_EMPTY_PATH, ".bar" }, |
| { "/.bar", "/", ".bar" }, |
| { "foo/bar", "foo", "bar" }, |
| { "/foo/bar", "/foo", "bar" }, |
| { "foo/bar", "foo", "bar" }, |
| { "foo./.bar", "foo.", ".bar" }, |
| { "../foo", "..", "foo" }, |
| { SVN_EMPTY_PATH, SVN_EMPTY_PATH, SVN_EMPTY_PATH }, |
| { "/flu\\b/\\blarg", "/flu\\b", "\\blarg" }, |
| { "/", "/", "" }, |
| { "X:/foo/bar", "X:/foo", "bar" }, |
| { "X:foo/bar", "X:foo", "bar" }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:/", "X:/", "" }, |
| { "X:/foo", "X:/", "foo" }, |
| { "X:foo", "X:", "foo" }, |
| { "//srv/shr", "//srv/shr", "" }, |
| { "//srv/shr/fld", "//srv/shr", "fld" }, |
| { "//srv/s r", "//srv/s r", "" }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "X:foo", SVN_EMPTY_PATH, "X:foo" }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (i = 0; i < COUNT_OF(paths); i++) |
| { |
| const char *dir, *base_name; |
| |
| svn_dirent_split(&dir, &base_name, paths[i][0], pool); |
| if (strcmp(dir, paths[i][1])) |
| { |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_split (%s) returned dirname '%s' instead of '%s'", |
| paths[i][0], dir, paths[i][1]); |
| } |
| if (strcmp(base_name, paths[i][2])) |
| { |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_split (%s) returned basename '%s' instead of '%s'", |
| paths[i][0], base_name, paths[i][2]); |
| } |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_split(apr_pool_t *pool) |
| { |
| apr_size_t i; |
| |
| static const char * const paths[][3] = { |
| { "", "", "" }, |
| { "bar", "", "bar" }, |
| { "foo/bar", "foo", "bar" }, |
| { "a/b/c", "a/b", "c" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(paths); i++) |
| { |
| const char *dir, *base_name; |
| |
| svn_relpath_split( &dir, &base_name, paths[i][0], pool); |
| if (strcmp(dir, paths[i][1])) |
| { |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_split (%s) returned dirname '%s' instead of '%s'", |
| paths[i][0], dir, paths[i][1]); |
| } |
| if (strcmp(base_name, paths[i][2])) |
| { |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_split (%s) returned basename '%s' instead of '%s'", |
| paths[i][0], base_name, paths[i][2]); |
| } |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| |
| static svn_error_t * |
| test_uri_split(apr_pool_t *pool) |
| { |
| apr_size_t i; |
| |
| static const char * const paths[][3] = { |
| { "http://server/foo/bar", "http://server/foo", "bar" }, |
| { "http://server/dir/foo/bar", "http://server/dir/foo", "bar" }, |
| { "http://server/some%20dir/foo%20bar", "http://server/some%20dir", "foo bar" }, |
| { "http://server/foo", "http://server", "foo" }, |
| { "http://server", "http://server", "" }, |
| { "file://", "file://", "" }, |
| { "file:///a", "file://", "a" } |
| }; |
| |
| for (i = 0; i < COUNT_OF(paths); i++) |
| { |
| const char *dir, *base_name; |
| |
| svn_uri_split(&dir, &base_name, paths[i][0], pool); |
| if (strcmp(dir, paths[i][1])) |
| { |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_split (%s) returned dirname '%s' instead of '%s'", |
| paths[i][0], dir, paths[i][1]); |
| } |
| if (strcmp(base_name, paths[i][2])) |
| { |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_split (%s) returned basename '%s' instead of '%s'", |
| paths[i][0], base_name, paths[i][2]); |
| } |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| /* Paths to test and the expected result, for ancestor tests. */ |
| typedef struct testcase_ancestor_t { |
| const char *path1; |
| const char *path2; |
| const char *result; |
| } testcase_ancestor_t; |
| |
| static const testcase_ancestor_t dirent_ancestor_tests[] = |
| { |
| { "", "", "" }, |
| { "", "foo", "foo" }, |
| { "", ".bar", ".bar" }, |
| { "", "/", NULL }, |
| { "", "/foo", NULL }, |
| { "/", "", NULL }, |
| { "/", "foo", NULL }, |
| { "/", "/", "" }, |
| { "/", "/foo", "foo" }, |
| { "/", "bar/bla", NULL }, |
| { "/foo", "/foo", "" }, |
| { "/foo", "/foot", NULL }, |
| { "/foo", "/foo/bar", "bar" }, |
| { "/foo/bar", "/foot/bar", NULL }, |
| { "/foot", "/foo", NULL }, |
| { "/foo/bar/bla", "/foo/bar", NULL }, |
| { "/foo/bar", "/foo/bar/bla", "bla" }, |
| { "foo/bar", "foo", NULL }, |
| { "/foo/bar", "foo", NULL }, |
| { "/.bar", "/", NULL }, |
| { "/foo/bar", "/foo", NULL }, |
| { "foo", "foo/bar", "bar" }, |
| { "foo.", "foo./.bar", ".bar" }, |
| { "X:foo", "X:bar", NULL }, |
| { "../foo", "..", NULL }, |
| { "/foo/bar/zig", "/foo", NULL }, |
| { "/foo/bar/zig", "/foo/ba", NULL }, |
| { "/foo/bar/zig", "/foo/bar/zi", NULL }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "", "C:", NULL }, |
| { "", "C:foo", NULL }, |
| { "", "C:/", NULL }, |
| { "", "C:/foo", NULL }, |
| { "X", "X:", NULL }, |
| { "X", "X:foo", NULL }, |
| { "X", "X:/", NULL }, |
| { "X", "X:/foo", NULL }, |
| { "X:", "X:", "" }, |
| { "X:", "X:foo", "foo" }, |
| { "X:", "X:/", NULL }, |
| { "X:", "X:/foo", NULL }, |
| { "X:/", "X:", NULL }, |
| { "X:/", "X:foo", NULL }, |
| { "X:/", "X:/", "" }, |
| { "X:/", "X:/foo", "foo" }, |
| { "X:/foo", "X:/", NULL }, |
| { "A:/foo", "A:/foo/bar", "bar" }, |
| { "A:/foo", "A:/foot", NULL }, |
| { "A:/foo/bar/zig", "A:/foo", NULL }, |
| { "A:/foo/bar/zig", "A:/foo/ba", NULL }, |
| { "A:/foo/bar/zig", "A:/foo/bar/zi", NULL }, |
| { "//srv", "//srv/share", NULL }, |
| { "//srv", "//srv/shr/fld", NULL }, |
| { "//srv/shr", "//srv", NULL }, |
| { "//srv/share", "//vrs/share", NULL }, |
| { "//srv/share", "//srv/share/foo", "foo" }, |
| { "//srv/shr", "//srv/shr/fld", "fld" }, |
| { "//srv/s r", "//srv/s r/fld", "fld" }, |
| { "//srv/shr/fld", "//srv/shr", NULL }, |
| { "//srv/shr/fld", "//srv2/shr/fld", NULL }, |
| { "//srv/shr/fld", "//srv/shr/f", NULL }, |
| { "/", "//srv/share", NULL }, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "", "C:", "C:" }, |
| { "", "C:/foo", "C:/foo" }, |
| { "X:", "X:foo", NULL }, |
| #endif |
| }; |
| |
| static svn_error_t * |
| test_dirent_is_ancestor(apr_pool_t *pool) |
| { |
| const testcase_ancestor_t *t; |
| |
| for (t = dirent_ancestor_tests; |
| t < dirent_ancestor_tests + COUNT_OF(dirent_ancestor_tests); |
| t++) |
| { |
| svn_boolean_t retval; |
| |
| retval = svn_dirent_is_ancestor(t->path1, t->path2); |
| if (!!t->result != retval) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_is_ancestor (%s, %s) returned %s instead of %s", |
| t->path1, t->path2, retval ? "TRUE" : "FALSE", |
| t->result ? "TRUE" : "FALSE"); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static const testcase_ancestor_t relpath_ancestor_tests[] = |
| { |
| { "", "", "" }, |
| { "", "foo", "foo" }, |
| { "", ".bar", ".bar" }, |
| { "", "bar/bla", "bar/bla" }, |
| { "foo", "foo", "" }, |
| { "foo", "foo/bar", "bar" }, |
| { "foo", "foot", NULL }, |
| { "foo.", "foo./.bar", ".bar" }, |
| { "foot", "foo", NULL }, |
| { "foo/bar", "foo", NULL }, |
| { "foo/bar", "foo/bar/bla", "bla" }, |
| { "foo/bar", "foot/bar", NULL }, |
| { "foo/bar/bla", "foo/bar", NULL }, |
| { "food/bar", "foo/bar", NULL }, |
| { "http:/server", "http:/server/q", "q" }, |
| { "svn:/server", "http:/server/q", NULL }, |
| /* These are relpaths so a colon is not special. */ |
| { "", "C:", "C:" }, |
| { "X:", "X:foo", NULL }, |
| { "X:", "X:/foo", "foo" }, |
| { "X:foo", "X:bar", NULL }, |
| }; |
| |
| static const testcase_ancestor_t uri_ancestor_tests[] = |
| { |
| { "http://test", "http://test", "" }, |
| { "http://test", "http://taste", NULL }, |
| { "http://test", "http://test/foo", "foo" }, |
| { "http://test", "file://test/foo", NULL }, |
| { "http://test", "http://testf", NULL }, |
| { "http://", "http://test", NULL }, |
| { "http://server", "http://server/q", "q" }, |
| { "svn://server", "http://server/q", NULL }, |
| { "http://foo/bar", "http://foo", NULL }, |
| { "http://foo/bar", "http://foo/ba", NULL }, |
| }; |
| |
| static svn_error_t * |
| test_uri_is_ancestor(apr_pool_t *pool) |
| { |
| const testcase_ancestor_t *t; |
| |
| for (t = uri_ancestor_tests; |
| t < uri_ancestor_tests + COUNT_OF(uri_ancestor_tests); |
| t++) |
| { |
| svn_boolean_t retval; |
| |
| retval = svn_uri__is_ancestor(t->path1, t->path2); |
| if (!!t->result != retval) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_is_ancestor (%s, %s) returned %s instead of %s", |
| t->path1, t->path2, retval ? "TRUE" : "FALSE", |
| t->result ? "TRUE" : "FALSE"); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_skip_ancestor(apr_pool_t *pool) |
| { |
| const testcase_ancestor_t *t; |
| |
| for (t = dirent_ancestor_tests; |
| t < dirent_ancestor_tests + COUNT_OF(dirent_ancestor_tests); |
| t++) |
| { |
| const char* retval; |
| |
| retval = svn_dirent_skip_ancestor(t->path1, t->path2); |
| if ((t->result == NULL) |
| ? (retval != NULL) |
| : (retval == NULL || strcmp(t->result, retval) != 0)) |
| return svn_error_createf( |
| SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_skip_ancestor (%s, %s) returned %s instead of %s", |
| t->path1, t->path2, retval, t->result); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_skip_ancestor(apr_pool_t *pool) |
| { |
| const testcase_ancestor_t *t; |
| |
| for (t = relpath_ancestor_tests; |
| t < relpath_ancestor_tests + COUNT_OF(relpath_ancestor_tests); |
| t++) |
| { |
| const char* retval; |
| |
| retval = svn_relpath_skip_ancestor(t->path1, t->path2); |
| if ((t->result == NULL) |
| ? (retval != NULL) |
| : (retval == NULL || strcmp(t->result, retval) != 0)) |
| return svn_error_createf( |
| SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_skip_ancestor (%s, %s) returned %s instead of %s", |
| t->path1, t->path2, retval, t->result); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_uri_skip_ancestor(apr_pool_t *pool) |
| { |
| const testcase_ancestor_t *t; |
| |
| for (t = uri_ancestor_tests; |
| t < uri_ancestor_tests + COUNT_OF(uri_ancestor_tests); |
| t++) |
| { |
| const char* retval; |
| |
| retval = svn_uri_skip_ancestor(t->path1, t->path2, pool); |
| if ((t->result == NULL) |
| ? (retval != NULL) |
| : (retval == NULL || strcmp(t->result, retval) != 0)) |
| return svn_error_createf( |
| SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_skip_ancestor (%s, %s) returned %s instead of %s", |
| t->path1, t->path2, retval, t->result); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| /* Paths to test and the expected result, for get_longest_ancestor tests. */ |
| typedef struct testcase_get_longest_ancestor_t { |
| const char *path1; |
| const char *path2; |
| const char *result; |
| } testcase_get_longest_ancestor_t; |
| |
| static svn_error_t * |
| test_dirent_get_longest_ancestor(apr_pool_t *pool) |
| { |
| const testcase_get_longest_ancestor_t *t; |
| static const testcase_get_longest_ancestor_t tests[] = { |
| { "/foo", "/foo/bar", "/foo"}, |
| { "/foo/bar", "foo/bar", SVN_EMPTY_PATH}, |
| { "/", "/foo", "/"}, |
| { SVN_EMPTY_PATH, "foo", SVN_EMPTY_PATH}, |
| { SVN_EMPTY_PATH, ".bar", SVN_EMPTY_PATH}, |
| { "/.bar", "/", "/"}, |
| { "foo/bar", "foo", "foo"}, |
| { "/foo/bar", "/foo", "/foo"}, |
| { "/rif", "/raf", "/"}, |
| { "foo", "bar", SVN_EMPTY_PATH}, |
| { "foo", "foo/bar", "foo"}, |
| { "foo.", "foo./.bar", "foo."}, |
| { SVN_EMPTY_PATH, SVN_EMPTY_PATH, SVN_EMPTY_PATH}, |
| { "/", "/", "/"}, |
| { "X:foo", "Y:foo", SVN_EMPTY_PATH}, |
| { "X:/folder1", "Y:/folder2", SVN_EMPTY_PATH}, |
| #ifdef SVN_USE_DOS_PATHS |
| { "X:/", "X:/", "X:/"}, |
| { "X:/foo/bar/A/D/H/psi", "X:/foo/bar/A/B", "X:/foo/bar/A" }, |
| { "X:/foo/bar/boo", "X:/foo/bar/baz/boz", "X:/foo/bar"}, |
| { "X:foo/bar", "X:foo/bar/boo", "X:foo/bar"}, |
| { "//srv/shr", "//srv/shr/fld", "//srv/shr" }, |
| { "//srv/shr/fld", "//srv/shr", "//srv/shr" }, |
| { "//srv/shr/fld", "//srv2/shr/fld", SVN_EMPTY_PATH }, |
| { "X:/foo", "X:/", "X:/"}, |
| { "X:/folder1", "X:/folder2", "X:/"}, |
| { "X:/", "X:/foo", "X:/"}, |
| { "X:", "X:foo", "X:"}, |
| { "X:", "X:/", SVN_EMPTY_PATH}, |
| { "X:foo", "X:bar", "X:"}, |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "X:/foo", "X:", "X:"}, |
| { "X:/folder1", "X:/folder2", "X:"}, |
| { "X:", "X:foo", SVN_EMPTY_PATH}, |
| { "X:foo", "X:bar", SVN_EMPTY_PATH}, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| const char *retval; |
| |
| retval = svn_dirent_get_longest_ancestor(t->path1, t->path2, pool); |
| |
| if (strcmp(t->result, retval)) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_get_longest_ancestor (%s, %s) returned %s instead of %s", |
| t->path1, t->path2, retval, t->result); |
| |
| /* changing the order of the paths should return the same results */ |
| retval = svn_dirent_get_longest_ancestor(t->path2, t->path1, pool); |
| |
| if (strcmp(t->result, retval)) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_get_longest_ancestor (%s, %s) returned %s instead of %s", |
| t->path2, t->path1, retval, t->result); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_get_longest_ancestor(apr_pool_t *pool) |
| { |
| const testcase_get_longest_ancestor_t *t; |
| static const testcase_get_longest_ancestor_t tests[] = { |
| { "foo", "foo/bar", "foo"}, |
| { "foo/bar", "foo/bar", "foo/bar"}, |
| { "", "foo", ""}, |
| { "", "foo", ""}, |
| { "", ".bar", ""}, |
| { ".bar", "", ""}, |
| { "foo/bar", "foo", "foo"}, |
| { "foo/bar", "foo", "foo"}, |
| { "rif", "raf", ""}, |
| { "foo", "bar", ""}, |
| { "foo", "foo/bar", "foo"}, |
| { "foo.", "foo./.bar", "foo."}, |
| { "", "", ""}, |
| { "http:/test", "http:/test", "http:/test"}, |
| { "http:/test", "http:/taste", "http:"}, |
| { "http:/test", "http:/test/foo", "http:/test"}, |
| { "http:/test", "file:/test/foo", ""}, |
| { "http:/test", "http:/testF", "http:"}, |
| { "file:/A/C", "file:/B/D", "file:"}, |
| { "file:/A/C", "file:/A/D", "file:/A"}, |
| { "X:/foo", "X:", "X:"}, |
| { "X:/folder1", "X:/folder2", "X:"}, |
| { "X:", "X:foo", ""}, |
| { "X:foo", "X:bar", ""}, |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| const char *retval; |
| |
| retval = svn_relpath_get_longest_ancestor(t->path1, t->path2, pool); |
| |
| if (strcmp(t->result, retval)) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_get_longest_ancestor (%s, %s) returned " |
| "%s instead of %s", |
| t->path1, t->path2, retval, t->result); |
| |
| /* changing the order of the paths should return the same results */ |
| retval = svn_relpath_get_longest_ancestor(t->path2, t->path1, pool); |
| |
| if (strcmp(t->result, retval)) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath_get_longest_ancestor (%s, %s) returned " |
| "%s instead of %s", |
| t->path2, t->path1, retval, t->result); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_uri_get_longest_ancestor(apr_pool_t *pool) |
| { |
| const testcase_get_longest_ancestor_t *t; |
| static const testcase_get_longest_ancestor_t tests[] = { |
| { "http://test", "http://test", "http://test"}, |
| { "http://test", "http://taste", SVN_EMPTY_PATH}, |
| { "http://test", "http://test/foo", "http://test"}, |
| { "http://test", "file://test/foo", SVN_EMPTY_PATH}, |
| { "http://test", "http://testf", SVN_EMPTY_PATH}, |
| { "http://", "http://test", SVN_EMPTY_PATH}, |
| { "file:///A/C", "file:///B/D", SVN_EMPTY_PATH}, |
| { "file:///A/C", "file:///A/D", "file:///A"}, |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| const char *retval; |
| |
| retval = svn_uri_get_longest_ancestor(t->path1, t->path2, pool); |
| |
| if (strcmp(t->result, retval)) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_get_longest_ancestor (%s, %s) returned %s instead of %s", |
| t->path1, t->path2, retval, t->result); |
| |
| /* changing the order of the paths should return the same results */ |
| retval = svn_uri_get_longest_ancestor(t->path2, t->path1, pool); |
| |
| if (strcmp(t->result, retval)) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_get_longest_ancestor (%s, %s) returned %s instead of %s", |
| t->path2, t->path1, retval, t->result); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_is_child(apr_pool_t *pool) |
| { |
| int i, j; |
| |
| static const char * const paths[] = { |
| "/foo/bar", |
| "/foo/bars", |
| "/foo/baz", |
| "/foo/bar/baz", |
| "/flu/blar/blaz", |
| "/foo/bar/baz/bing/boom", |
| SVN_EMPTY_PATH, |
| "foo", |
| ".foo", |
| "/", |
| "foo2", |
| #ifdef SVN_USE_DOS_PATHS |
| "//srv", |
| "//srv2", |
| "//srv/shr", |
| "//srv/shr/fld", |
| "H:/foo/bar", |
| "H:/foo/baz", |
| "H:/foo/bar/baz", |
| "H:/flu/blar/blaz", |
| "H:/foo/bar/baz/bing/boom", |
| "H:/", |
| "H:/iota", |
| "H:", |
| "H:foo", |
| "H:foo/baz", |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| /* Maximum number of path[] items for all platforms */ |
| #define MAX_PATHS 32 |
| |
| static const char * const |
| remainders[COUNT_OF(paths)][MAX_PATHS] = { |
| { 0, 0, 0, "baz", 0, "baz/bing/boom", 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, "bing/boom", 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, "foo", ".foo", 0, "foo2", |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { "foo/bar", "foo/bars", "foo/baz", "foo/bar/baz", "flu/blar/blaz", |
| "foo/bar/baz/bing/boom", 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| #ifdef SVN_USE_DOS_PATHS |
| /* //srv paths */ |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, "shr", "shr/fld", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, "fld", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| /* H:/ paths */ |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, "baz", 0, "baz/bing/boom", 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, "bing/boom", 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, "foo/bar", "foo/baz", "foo/bar/baz", "flu/blar/blaz", |
| "foo/bar/baz/bing/boom", 0, "iota", 0, 0, 0 }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| /* H: paths */ |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "foo", "foo/baz" }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "baz" }, |
| { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
| 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| for (i = 0; i < COUNT_OF(paths); i++) |
| { |
| for (j = 0; j < COUNT_OF(paths); j++) |
| { |
| const char *remainder; |
| |
| remainder = svn_dirent_is_child(paths[i], paths[j], pool); |
| |
| if (((remainder) && (! remainders[i][j])) |
| || ((! remainder) && (remainders[i][j])) |
| || (remainder && strcmp(remainder, remainders[i][j]))) |
| return svn_error_createf |
| (SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_is_child (%s, %s) returned '%s' instead of '%s'", |
| paths[i], paths[j], |
| remainder ? remainder : "(null)", |
| remainders[i][j] ? remainders[i][j] : "(null)" ); |
| } |
| } |
| |
| #undef NUM_TEST_PATHS |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_get_absolute(apr_pool_t *pool) |
| { |
| int i; |
| const char *curdir; |
| char buf[8192]; |
| #ifdef SVN_USE_DOS_PATHS |
| const char *curdironc; |
| char curdrive[3] = "C:"; |
| #endif /* SVN_USE_DOS_PATHS */ |
| |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| /* '%' will be replaced by the current working dir. */ |
| { "abc", "%/abc" }, |
| { SVN_EMPTY_PATH, "%" }, |
| #ifdef SVN_USE_DOS_PATHS |
| /* '@' will be replaced by the current working dir on C:\. */ |
| /* '$' will be replaced by the current drive */ |
| { "C:/", "C:/" }, |
| { "C:/abc", "C:/abc" }, |
| { "C:abc", "@/abc" }, |
| { "C:", "@" }, |
| { "/", "$/" }, |
| { "/x/abc", "$/x/abc" }, |
| { "c:/", "C:/" }, |
| { "c:/AbC", "C:/AbC" }, |
| { "c:abc", "@/abc" }, |
| /* svn_dirent_get_absolute will check existence of this UNC shares on the |
| test machine, so we can't really test this. |
| { "//srv/shr", "//srv/shr" }, |
| { "//srv/shr/fld", "//srv/shr" }, |
| { "//srv/shr/fld/subfld", "//srv/shr/fld" }, */ |
| #else /* !SVN_USE_DOS_PATHS */ |
| { "/abc", "/abc" }, |
| { "/x/abc", "/x/abc" }, |
| { "X:", "%/X:" }, |
| { "X:abc", "%/X:abc" }, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| |
| if (! getcwd(buf, sizeof(buf))) |
| return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed"); |
| |
| curdir = svn_dirent_internal_style(buf, pool); |
| |
| #ifdef SVN_USE_DOS_PATHS |
| if (! getdcwd(3, buf, sizeof(buf))) /* 3 stands for drive C: */ |
| return svn_error_create(SVN_ERR_BASE, NULL, "getdcwd() failed"); |
| |
| curdironc = svn_dirent_internal_style(buf, pool); |
| curdrive[0] = curdir[0]; |
| #endif /* SVN_USE_DOS_PATHS */ |
| |
| for (i = 0 ; i < COUNT_OF(tests) ; i++ ) |
| { |
| const char *path = tests[i].path; |
| const char *expect = tests[i].result; |
| const char *expect_abs, *result; |
| |
| expect_abs = expect; |
| if (*expect == '%') |
| expect_abs = apr_pstrcat(pool, curdir, expect + 1, SVN_VA_NULL); |
| #ifdef SVN_USE_DOS_PATHS |
| if (*expect == '@') |
| expect_abs = apr_pstrcat(pool, curdironc, expect + 1, SVN_VA_NULL); |
| |
| if (*expect == '$') |
| expect_abs = apr_pstrcat(pool, curdrive, expect + 1, SVN_VA_NULL); |
| |
| /* Remove double '/' when CWD was the root dir (E.g. C:/) */ |
| expect_abs = svn_dirent_canonicalize(expect_abs, pool); |
| #endif /* SVN_USE_DOS_PATHS */ |
| |
| SVN_ERR(svn_dirent_get_absolute(&result, path, pool)); |
| if (strcmp(result, expect_abs)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_get_absolute(\"%s\") returned " |
| "\"%s\". expected \"%s\"", |
| path, result, expect_abs); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| #ifdef WIN32 |
| static svn_error_t * |
| test_dirent_get_absolute_from_lc_drive(apr_pool_t *pool) |
| { |
| char current_dir[1024]; |
| char current_dir_on_C[1024]; |
| char *dir_on_c; |
| svn_error_t *err; |
| apr_hash_t *dirents; |
| apr_hash_index_t *hi; |
| const char *some_dir_on_C = NULL; |
| |
| if (! getcwd(current_dir, sizeof(current_dir))) |
| return svn_error_create(SVN_ERR_BASE, NULL, "getcwd() failed"); |
| |
| /* 3 stands for drive C: */ |
| if (! getdcwd(3, current_dir_on_C, sizeof(current_dir_on_C))) |
| return svn_error_create(SVN_ERR_BASE, NULL, "getdcwd() failed"); |
| |
| SVN_ERR(svn_io_get_dirents3(&dirents, "C:\\", TRUE, pool, pool)); |
| |
| /* We need a directory on 'C:\' to switch to lower case and back. |
| We use the first directory we can find that is not the CWD and |
| where we can chdir to */ |
| |
| for (hi = apr_hash_first(pool, dirents); hi; hi = apr_hash_next(hi)) |
| { |
| const char *dir = apr_hash_this_key(hi); |
| svn_io_dirent2_t *de = apr_hash_this_val(hi); |
| |
| if (de->kind == svn_node_dir && |
| strcmp(dir, current_dir_on_C)) |
| { |
| dir = svn_dirent_join("C:/", dir, pool); |
| if (!chdir(dir)) |
| { |
| chdir(current_dir_on_C); /* Switch back to old CWD */ |
| some_dir_on_C = dir; |
| break; |
| } |
| } |
| } |
| |
| if (!some_dir_on_C) |
| return svn_error_create(SVN_ERR_BASE, NULL, |
| "No usable test directory found in C:\\"); |
| |
| /* Use the test path, but now with a lower case driveletter */ |
| dir_on_c = apr_pstrdup(pool, some_dir_on_C); |
| dir_on_c[0] = (char)tolower(dir_on_c[0]); |
| |
| chdir(dir_on_c); |
| |
| err = test_dirent_get_absolute(pool); |
| |
| /* Change back to original directory for next tests */ |
| chdir("C:\\"); /* Switch to upper case */ |
| chdir(current_dir_on_C); /* Switch cwd on C: */ |
| chdir(current_dir); /* Switch back to original cwd */ |
| return err; |
| } |
| #endif |
| |
| static svn_error_t * |
| test_dirent_condense_targets(apr_pool_t *pool) |
| { |
| int i; |
| struct { |
| const char *paths[8]; |
| const char *common; |
| const char *results[8]; /* must be same size as paths */ |
| } tests[] = { |
| { { "/dir", "/dir/file", NULL }, NULL, { "", "file" } }, |
| { { "/dir1", "/dir2", NULL }, NULL, { "dir1", "dir2" } }, |
| { { "dir1", "dir2", NULL }, NULL, { "dir1", "dir2" } }, |
| #ifdef SVN_USE_DOS_PATHS |
| { {"C:/", "C:/zeta", NULL}, "C:/", {"", "zeta"} }, |
| { {"C:/dir", "C:/dir/zeta", NULL}, "C:/dir", {"", "zeta"} }, |
| { {"C:/dir/omega", "C:/dir/zeta", NULL}, "C:/dir", {"omega", "zeta" } }, |
| { {"C:/dir", "D:/dir", NULL}, "", {"C:/dir", "D:/dir"} }, |
| { {"C:A", "C:dir/b", NULL}, NULL, {"A", "dir/b"} }, |
| #else |
| { { "/dir", "/dir/file", NULL }, "/dir", { "", "file" } }, |
| { { "/dir1", "/dir2", NULL }, "/", { "dir1", "dir2" } }, |
| #endif |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| int j; |
| const char* common; |
| apr_array_header_t *hdr = apr_array_make(pool, 8, sizeof(const char*)); |
| apr_array_header_t *condensed; |
| svn_boolean_t skip = FALSE; |
| |
| for (j = 0; j < COUNT_OF(tests[i].paths); j++) |
| { |
| if (tests[i].paths[j] != NULL) |
| { |
| APR_ARRAY_PUSH(hdr, const char*) = tests[i].paths[j]; |
| #ifdef SVN_USE_DOS_PATHS |
| /* For tests that are referencing a D: drive, specifically test |
| if such a drive exists on the system. If not, skip the test |
| (svn_dirent_condense_targets will fail, because |
| apr_filepath_merge will produce an APR_EBADPATH error). */ |
| if (strncmp(tests[i].paths[j], "D:", 2) == 0 |
| && GetDriveType("D:\\") == DRIVE_NO_ROOT_DIR) |
| { |
| /* There is no D: drive, skip this. */ |
| skip = TRUE; |
| break; |
| } |
| #endif |
| } |
| else |
| break; |
| } |
| |
| if (skip) |
| continue; |
| |
| SVN_ERR(svn_dirent_condense_targets(&common, &condensed, hdr, |
| FALSE, pool, pool)); |
| |
| if (tests[i].common != NULL && strcmp(common, tests[i].common)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_condense_targets returned common " |
| "\"%s\". expected \"%s\"", |
| common, tests[i].common); |
| |
| for (j = 0; j < COUNT_OF(tests[i].paths); j++) |
| { |
| if (tests[i].paths[j] == NULL || tests[i].results[j] == NULL) |
| break; |
| |
| if (strcmp(APR_ARRAY_IDX(condensed, j, const char*), |
| tests[i].results[j])) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_condense_targets returned first" |
| "\"%s\". expected \"%s\"", |
| APR_ARRAY_IDX(condensed, j, const char*), |
| tests[i].results[j]); |
| } |
| } |
| |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_uri_condense_targets(apr_pool_t *pool) |
| { |
| int i; |
| struct { |
| const char *paths[8]; |
| const char *common; |
| const char *results[8]; /* must be same size as paths */ |
| } tests[] = { |
| /* { { url1, url2, url3 }, |
| common_url, |
| { relpath1, relpath2, relpath3 } } |
| */ |
| { { "sc://s/A", "sc://s/B", "sc://s" }, |
| "sc://s", |
| { "A", "B", "" } }, |
| { { "sc://S/A", "sc://S/B", "sc://S" }, |
| "sc://s", |
| { "A", "B", "" } }, |
| { { "sc://A/A", "sc://B/B", "sc://s" }, |
| "", |
| { "sc://a/A", "sc://b/B", "sc://s" } }, |
| { { "sc://A/A", "sc://A/a/B", "sc://a/Q" }, |
| "sc://a", |
| { "A", "a/B", "Q"} }, |
| { { "sc://server/foo%20bar", "sc://server/baz", "sc://server/blarg" }, |
| "sc://server", |
| { "foo bar", "baz", "blarg"} }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| int j; |
| const char* common; |
| apr_array_header_t *hdr = apr_array_make(pool, 8, sizeof(const char*)); |
| apr_array_header_t *condensed; |
| |
| for (j = 0; j < COUNT_OF(tests[i].paths); j++) |
| { |
| if (tests[i].paths[j] != NULL) |
| APR_ARRAY_PUSH(hdr, const char*) = tests[i].paths[j]; |
| else |
| break; |
| } |
| |
| SVN_ERR(svn_uri_condense_targets(&common, &condensed, hdr, |
| FALSE, pool, pool)); |
| |
| if (tests[i].common != NULL && strcmp(common, tests[i].common)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_condense_targets returned common " |
| "\"%s\". expected \"%s\"", |
| common, tests[i].common); |
| |
| for (j = 0; j < COUNT_OF(tests[i].paths); j++) |
| { |
| if (tests[i].paths[j] == NULL || tests[i].results[j] == NULL) |
| break; |
| |
| if (strcmp(APR_ARRAY_IDX(condensed, j, const char*), |
| tests[i].results[j])) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_condense_targets returned first" |
| "\"%s\". expected \"%s\"", |
| APR_ARRAY_IDX(condensed, j, const char*), |
| tests[i].results[j]); |
| } |
| } |
| |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_local_style(apr_pool_t *pool) |
| { |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "", "." }, |
| { ".", "." }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "A:/", "A:\\" }, |
| { "A:/file", "A:\\file" }, |
| { "dir/file", "dir\\file" }, |
| { "/", "\\" }, |
| { "//server/share/dir", "\\\\server\\share\\dir" }, |
| { "//server/sh re/dir", "\\\\server\\sh re\\dir" }, |
| #else |
| { "a:/file", "a:/file" }, |
| { "dir/file", "dir/file" }, |
| { "/", "/" }, |
| #endif |
| }; |
| int i; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *local = svn_dirent_local_style(tests[i].path, pool); |
| |
| if (strcmp(local, tests[i].result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_local_style(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| tests[i].path, local, tests[i].result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_internal_style(apr_pool_t *pool) |
| { |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "", "" }, |
| { ".", "" }, |
| { "/", "/" }, |
| { "file", "file" }, |
| { "dir/file", "dir/file" }, |
| { "dir/file/./.", "dir/file" }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "A:\\", "A:/" }, |
| { "A:\\file", "A:/file" }, |
| { "A:file", "A:file" }, |
| { "a:\\", "A:/" }, |
| { "a:/", "A:/" }, |
| { "a:\\file", "A:/file" }, |
| { "a:file", "A:file" }, |
| { "dir\\file", "dir/file" }, |
| { "\\\\srv\\shr\\dir", "//srv/shr/dir" }, |
| { "\\\\srv\\shr\\", "//srv/shr" }, |
| { "\\\\srv\\s r\\", "//srv/s r" }, |
| { "//srv/shr", "//srv/shr" }, |
| { "//srv/s r", "//srv/s r" }, |
| { "//srv/s r", "//srv/s r" }, |
| #else |
| { "a:/", "a:" }, /* Wrong but expected for svn_path_*() */ |
| { "a:/file", "a:/file" }, |
| { "dir/file", "dir/file" }, |
| { "/", "/" }, |
| { "//server/share/dir", "/server/share/dir" }, |
| #endif |
| }; |
| int i; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *internal = svn_dirent_internal_style(tests[i].path, pool); |
| |
| if (strcmp(internal, tests[i].result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_internal_style(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| tests[i].path, internal, tests[i].result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_relpath_internal_style(apr_pool_t *pool) |
| { |
| struct { |
| const char *path; |
| const char *result; |
| } tests[] = { |
| { "", "" }, |
| { ".", "" }, |
| { "/", "" }, |
| { "file", "file" }, |
| { "dir/file", "dir/file" }, |
| { "a:/", "a:" }, |
| { "a:/file", "a:/file" }, |
| { "dir/file", "dir/file" }, |
| { "//server/share/dir", "server/share/dir" }, |
| { "a/./.", "a" }, |
| }; |
| int i; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *internal; |
| SVN_ERR(svn_relpath__make_internal(&internal, tests[i].path, pool, pool)); |
| |
| if (strcmp(internal, tests[i].result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_relpath__make_internal(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| tests[i].path, internal, tests[i].result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_from_file_url(apr_pool_t *pool) |
| { |
| struct { |
| const char *url; |
| const char *result; |
| } tests[] = { |
| { "file://", "/" }, |
| { "file:///dir", "/dir" }, |
| { "file:///dir/path", "/dir/path" }, |
| { "file://localhost", "/" }, |
| { "file://localhost/dir", "/dir" }, |
| { "file://localhost/dir/path", "/dir/path" }, |
| #ifdef SVN_USE_DOS_PATHS |
| { "file://server/share", "//server/share" }, |
| { "file://server/share/dir", "//server/share/dir" }, |
| { "file:///A:", "A:/" }, |
| { "file:///A:/dir", "A:/dir" }, |
| { "file:///A:dir", "A:dir" }, |
| { "file:///A%7C", "A:/" }, |
| { "file:///A%7C/dir", "A:/dir" }, |
| { "file:///A%7Cdir", "A:dir" }, |
| { "file:///A%7C%5Cdir", "A:/dir" }, |
| { "file:///A%7C%5Cdir%5Cfile", "A:/dir\\file" }, |
| { "file:///A:%5Cdir", "A:/dir" }, |
| { "file:///A:%5Cdir%5Cfile", "A:/dir\\file" }, |
| { "file://localhost/A:%5Cfile","A:/file"}, |
| { "file://localhost/A:file", "A:file"} |
| #else |
| { "file:///A:", "/A:" }, |
| { "file:///A:/dir", "/A:/dir" }, |
| { "file:///A:dir", "/A:dir" }, |
| { "file:///A%7C", "/A|" }, |
| { "file:///A%7C/dir", "/A|/dir" }, |
| { "file:///A%7Cdir", "/A|dir" }, |
| { "file:///A%7C%5Cdir", "/A|\\dir" }, |
| { "file:///A%7C%5Cdir%5Cfile", "/A|\\dir\\file" }, |
| { "file:///A:%5Cdir", "/A:\\dir" }, |
| { "file:///A:%5Cdir%5Cfile", "/A:\\dir\\file" }, |
| { "file://localhost/A:%5Cfile","/A:\\file" }, |
| { "file://localhost/A:file", "/A:file" } |
| #endif |
| }; |
| int i; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *result; |
| |
| SVN_ERR(svn_uri_get_dirent_from_file_url(&result, tests[i].url, pool)); |
| |
| if (strcmp(result, tests[i].result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_get_dirent_from_file_url(\"%s\") " |
| "returned \"%s\" expected \"%s\"", |
| tests[i].url, result, tests[i].result); |
| if (!svn_dirent_is_canonical(result, pool)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_get_dirent_from_file_url(\"%s\") " |
| "returned \"%s\", which is not canonical.", |
| tests[i].url, result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_from_file_url_errors(apr_pool_t *pool) |
| { |
| const char *bad_file_urls[] = { |
| /* error if scheme is not "file" */ |
| "http://localhost/dir", |
| "file+ssh://localhost/dir", |
| #ifndef SVN_USE_DOS_PATHS |
| "file://localhostwrongname/dir", /* error if host name not "localhost" */ |
| #endif |
| }; |
| int i; |
| |
| for (i = 0; i < COUNT_OF(bad_file_urls); i++) |
| { |
| const char *result; |
| svn_error_t *err; |
| |
| err = svn_uri_get_dirent_from_file_url(&result, bad_file_urls[i], |
| pool); |
| |
| if (err == NULL) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_get_dirent_from_file_url(\"%s\") " |
| "didn't return an error.", |
| bad_file_urls[i]); |
| svn_error_clear(err); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_file_url_from_dirent(apr_pool_t *pool) |
| { |
| struct { |
| const char *dirent; |
| const char *result; |
| } tests[] = { |
| #ifdef SVN_USE_DOS_PATHS |
| { "C:/file", "file:///C:/file" }, |
| { "C:/", "file:///C:" }, |
| { "C:/File#$", "file:///C:/File%23$" }, |
| /* We can't check these as svn_dirent_get_absolute() won't work |
| on shares that don't exist */ |
| /*{ "//server/share", "file://server/share" }, |
| { "//server/share/file", "file://server/share/file" },*/ |
| #else |
| { "/a/b", "file:///a/b" }, |
| { "/a", "file:///a" }, |
| { "/", "file://" }, |
| { "/File#$", "file:///File%23$" }, |
| #endif |
| }; |
| int i; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *result; |
| |
| SVN_ERR(svn_uri_get_file_url_from_dirent(&result, tests[i].dirent, |
| pool)); |
| |
| if (strcmp(result, tests[i].result)) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_uri_get_file_url_from_dirent(\"%s\") " |
| "returned \"%s\" expected \"%s\"", |
| tests[i].dirent, result, tests[i].result); |
| |
| SVN_TEST_ASSERT(svn_uri_is_canonical(result, pool)); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_dirent_is_under_root(apr_pool_t *pool) |
| { |
| struct { |
| const char *base_path; |
| const char *path; |
| svn_boolean_t under_root; |
| const char *result; |
| } tests[] = { |
| { "", "", TRUE, ""}, |
| { "", "r", TRUE, "r"}, |
| { "", "r/..", TRUE, ""}, |
| { "", "r/../..", FALSE}, |
| { "", "r/../../b", FALSE}, |
| { "", "..", FALSE}, |
| { "", "../r", FALSE}, |
| { "", "/", FALSE}, |
| { "", "/r", FALSE}, |
| { "", "/..", FALSE}, |
| { "b", "", TRUE, "b"}, |
| { "b", "r", TRUE, "b/r"}, |
| { "b", "r/..", TRUE, "b"}, |
| { "b", "r/../..", FALSE}, |
| { "b", "r/../../b", FALSE}, |
| { "b", "..", FALSE}, |
| { "b", "../r", FALSE}, |
| { "b", "../b", FALSE}, |
| { "b", "/", FALSE}, |
| { "b", "/r", FALSE}, |
| { "b", "/..", FALSE}, |
| { "/", "", TRUE, "/"}, |
| { "/", "r", TRUE, "/r"}, |
| { "/", "r/..", TRUE, "/"}, |
| { "/", "r/../..", FALSE}, |
| { "/", "r/../../b", FALSE}, |
| { "/", "..", FALSE}, |
| { "/", "../r", FALSE}, |
| { "/", "/", FALSE}, |
| { "/", "/r", FALSE}, |
| { "/", "/..", FALSE}, |
| { "/b", "", TRUE, "/b"}, |
| { "/b", "r", TRUE, "/b/r"}, |
| { "/b", "r/..", TRUE, "/b"}, |
| { "/b", "r/../..", FALSE}, |
| { "/b", "r/../../b", FALSE}, |
| { "/b", "..", FALSE}, |
| { "/b", "../r", FALSE}, |
| { "/b", "../b", FALSE}, |
| { "/b", "/", FALSE}, |
| { "/b", "/r", FALSE}, |
| { "/b", "/..", FALSE}, |
| { "/", "/base", FALSE}, |
| { "/aa", "/aa/bb", FALSE}, |
| { "/base", "/base2", FALSE}, |
| { "/b", "bb", TRUE, "/b/bb"}, |
| { "/b", "../bb", FALSE}, |
| { "/b", "r/./bb", TRUE, "/b/r/bb"}, |
| { "/b", "r/../bb", TRUE, "/b/bb"}, |
| { "/b", "r/../../bb", FALSE}, |
| { "/b", "./bb", TRUE, "/b/bb"}, |
| { "/b", ".", TRUE, "/b"}, |
| { "/b", "", TRUE, "/b"}, |
| { "b", "b", TRUE, "b/b"}, |
| #ifdef SVN_USE_DOS_PATHS |
| { "C:/file", "a\\d", TRUE, "C:/file/a/d"}, |
| { "C:/file", "aa\\..\\d", TRUE, "C:/file/d"}, |
| { "C:/file", "aa\\..\\..\\d", FALSE}, |
| #else |
| { "C:/file", "a\\d", TRUE, "C:/file/a\\d"}, |
| { "C:/file", "aa\\..\\d", TRUE, "C:/file/aa\\..\\d"}, |
| { "C:/file", "aa\\..\\..\\d", TRUE, "C:/file/aa\\..\\..\\d"}, |
| #endif /* SVN_USE_DOS_PATHS */ |
| }; |
| int i; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| svn_boolean_t under_root; |
| const char *result; |
| |
| SVN_ERR(svn_dirent_is_under_root(&under_root, |
| &result, |
| tests[i].base_path, |
| tests[i].path, |
| pool)); |
| |
| if (under_root != tests[i].under_root) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_is_under_root(..\"%s\", \"%s\"..)" |
| " returned %s expected %s.", |
| tests[i].base_path, |
| tests[i].path, |
| under_root ? "TRUE" : "FALSE", |
| tests[i].under_root ? "TRUE" : "FALSE"); |
| |
| if (under_root |
| && strcmp(result, tests[i].result) != 0) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_dirent_is_under_root(..\"%s\", \"%s\"..)" |
| " found \"%s\" expected \"%s\".", |
| tests[i].base_path, |
| tests[i].path, |
| result, |
| tests[i].result); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_fspath_is_canonical(apr_pool_t *pool) |
| { |
| const testcase_is_canonical_t *t; |
| static const testcase_is_canonical_t tests[] = { |
| { "", FALSE }, |
| { ".", FALSE }, |
| { "/", TRUE }, |
| { "/a", TRUE }, |
| { "/a/", FALSE }, |
| { "//a", FALSE }, |
| { "/a/b", TRUE }, |
| { "/a//b", FALSE }, |
| { "\\", FALSE }, |
| { "\\a", FALSE }, |
| { "/\\a", TRUE }, /* a single component */ |
| { "/a\\", TRUE }, /* a single component */ |
| { "/a\\b", TRUE }, /* a single component */ |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| svn_boolean_t canonical |
| = svn_fspath__is_canonical(t->path); |
| |
| if (t->canonical != canonical) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "svn_fspath__is_canonical(\"%s\") returned " |
| "\"%s\" expected \"%s\"", |
| t->path, |
| canonical ? "TRUE" : "FALSE", |
| t->canonical ? "TRUE" : "FALSE"); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_fspath_join(apr_pool_t *pool) |
| { |
| int i; |
| |
| static const char * const joins[][3] = { |
| { "/", "", "/" }, |
| { "/", "d", "/d" }, |
| { "/", "d/e", "/d/e" }, |
| { "/abc", "", "/abc" }, |
| { "/abc", "d", "/abc/d" }, |
| { "/abc", "d/e", "/abc/d/e" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(joins); i++ ) |
| { |
| char *result = svn_fspath__join(joins[i][0], joins[i][1], pool); |
| |
| SVN_TEST_STRING_ASSERT(result, joins[i][2]); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_fspath_skip_ancestor(apr_pool_t *pool) |
| { |
| int i, j; |
| |
| static const char * const paths[] = { |
| "/", |
| "/f", |
| "/foo", |
| "/foo/bar", |
| "/foo/bars", |
| "/foo/bar/baz", |
| }; |
| |
| static const char * const |
| remainders[COUNT_OF(paths)][COUNT_OF(paths)] = { |
| { "", "f", "foo", "foo/bar", "foo/bars", "foo/bar/baz" }, |
| { 0, "", 0, 0, 0, 0 }, |
| { 0, 0, "", "bar", "bars", "bar/baz" }, |
| { 0, 0, 0, "", 0, "baz" }, |
| { 0, 0, 0, 0, "", 0 }, |
| { 0, 0, 0, 0, 0, "" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(paths); i++) |
| { |
| for (j = 0; j < COUNT_OF(paths); j++) |
| { |
| const char *remainder |
| = svn_fspath__skip_ancestor(paths[i], paths[j]); |
| |
| SVN_TEST_STRING_ASSERT(remainder, remainders[i][j]); |
| } |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_fspath_dirname_basename_split(apr_pool_t *pool) |
| { |
| int i; |
| |
| static const struct { |
| const char *path; |
| const char *dirname; |
| const char *basename; |
| } tests[] = { |
| { "/", "/", "" }, |
| { "/a", "/", "a" }, |
| { "/abc", "/", "abc" }, |
| { "/x/abc", "/x", "abc" }, |
| { "/x/y/abc", "/x/y", "abc" }, |
| }; |
| |
| for (i = 0; i < COUNT_OF(tests); i++) |
| { |
| const char *result_dirname, *result_basename; |
| |
| result_dirname = svn_fspath__dirname(tests[i].path, pool); |
| SVN_TEST_STRING_ASSERT(result_dirname, tests[i].dirname); |
| |
| result_basename = svn_fspath__basename(tests[i].path, pool); |
| SVN_TEST_STRING_ASSERT(result_basename, tests[i].basename); |
| |
| svn_fspath__split(&result_dirname, &result_basename, tests[i].path, |
| pool); |
| SVN_TEST_STRING_ASSERT(result_dirname, tests[i].dirname); |
| SVN_TEST_STRING_ASSERT(result_basename, tests[i].basename); |
| } |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static svn_error_t * |
| test_fspath_get_longest_ancestor(apr_pool_t *pool) |
| { |
| const testcase_get_longest_ancestor_t *t; |
| |
| /* Paths to test and their expected results. Same as in |
| * test_relpath_get_longest_ancestor() but with '/' prefix. */ |
| static const testcase_get_longest_ancestor_t tests[] = { |
| { "/foo", "/foo/bar", "/foo" }, |
| { "/foo/bar", "/foo/bar", "/foo/bar" }, |
| { "/", "/foo", "/" }, |
| { "/", "/foo", "/" }, |
| { "/", "/.bar", "/" }, |
| { "/.bar", "/", "/" }, |
| { "/foo/bar", "/foo", "/foo" }, |
| { "/foo/bar", "/foo", "/foo" }, |
| { "/rif", "/raf", "/" }, |
| { "/foo", "/bar", "/" }, |
| { "/foo", "/foo/bar", "/foo" }, |
| { "/foo.", "/foo./.bar", "/foo." }, |
| { "/", "/", "/" }, |
| { "/http:/test", "/http:/test", "/http:/test" }, |
| { "/http:/test", "/http:/taste", "/http:" }, |
| { "/http:/test", "/http:/test/foo", "/http:/test" }, |
| { "/http:/test", "/file:/test/foo", "/" }, |
| { "/http:/test", "/http:/testF", "/http:" }, |
| { "/file:/A/C", "/file:/B/D", "/file:" }, |
| { "/file:/A/C", "/file:/A/D", "/file:/A" }, |
| { "/X:/foo", "/X:", "/X:" }, |
| { "/X:/folder1", "/X:/folder2", "/X:" }, |
| { "/X:", "/X:foo", "/" }, |
| { "/X:foo", "/X:bar", "/" }, |
| }; |
| |
| for (t = tests; t < tests + COUNT_OF(tests); t++) |
| { |
| const char *result; |
| |
| result = svn_fspath__get_longest_ancestor(t->path1, t->path2, pool); |
| SVN_TEST_STRING_ASSERT(t->result, result); |
| |
| /* changing the order of the paths should return the same result */ |
| result = svn_fspath__get_longest_ancestor(t->path2, t->path1, pool); |
| SVN_TEST_STRING_ASSERT(t->result, result); |
| } |
| return SVN_NO_ERROR; |
| } |
| |
| struct cert_match_dns_test { |
| const char *pattern; |
| const char *hostname; |
| svn_boolean_t expected; |
| }; |
| |
| static svn_error_t * |
| run_cert_match_dns_tests(struct cert_match_dns_test *tests, apr_pool_t *pool) |
| { |
| struct cert_match_dns_test *ct; |
| apr_pool_t *iterpool = svn_pool_create(pool); |
| |
| for (ct = tests; ct->pattern; ct++) |
| { |
| svn_boolean_t result; |
| svn_string_t *pattern, *hostname; |
| |
| svn_pool_clear(iterpool); |
| |
| pattern = svn_string_create(ct->pattern, iterpool); |
| hostname = svn_string_create(ct->hostname, iterpool); |
| |
| result = svn_cert__match_dns_identity(pattern, hostname); |
| if (result != ct->expected) |
| return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, |
| "Expected %s but got %s for pattern '%s' on " |
| "hostname '%s'", |
| ct->expected ? "match" : "no match", |
| result ? "match" : "no match", |
| pattern->data, hostname->data); |
| |
| } |
| |
| svn_pool_destroy(iterpool); |
| |
| return SVN_NO_ERROR; |
| } |
| |
| static struct cert_match_dns_test cert_match_dns_tests[] = { |
| { "foo.example.com", "foo.example.com", TRUE }, /* exact match */ |
| { "foo.example.com", "FOO.EXAMPLE.COM", TRUE }, /* case differences */ |
| { "FOO.EXAMPLE.COM", "foo.example.com", TRUE }, |
| { "*.example.com", "FoO.ExAmPlE.CoM", TRUE }, |
| { "*.ExAmPlE.CoM", "foo.example.com", TRUE }, |
| { "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz", TRUE }, |
| { "abcdefghijklmnopqrstuvwxyz", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", TRUE }, |
| { "foo.example.com", "bar.example.com", FALSE }, /* difference at start */ |
| { "foo.example.com", "foo.example.net", FALSE }, /* difference at end */ |
| { "foo.example.com", "foo.example.commercial", FALSE }, /* hostname longer */ |
| { "foo.example.commercial", "foo.example.com", FALSE }, /* pattern longer */ |
| { "foo.example.comcom", "foo.example.com", FALSE }, /* repeated suffix */ |
| { "foo.example.com", "foo.example.comcom", FALSE }, |
| { "foo.example.com.com", "foo.example.com", FALSE }, |
| { "foo.example.com", "foo.example.com.com", FALSE }, |
| { "foofoo.example.com", "foo.example.com", FALSE }, /* repeated prefix */ |
| { "foo.example.com", "foofoo.example.com", FALSE }, |
| { "foo.foo.example.com", "foo.example.com", FALSE }, |
| { "foo.example.com", "foo.foo.example.com", FALSE }, |
| { "foo.*.example.com", "foo.bar.example.com", FALSE }, /* RFC 6125 s. 6.4.3 |
| Rule 1 */ |
| { "*.example.com", "foo.example.com", TRUE }, /* RFC 6125 s. 6.4.3 Rule 2 */ |
| { "*.example.com", "bar.foo.example.com", FALSE }, /* Rule 2 */ |
| { "*.example.com", "example.com", FALSE }, /* Rule 2 */ |
| { "*.example.com", ".example.com", FALSE }, /* RFC doesn't say what to do |
| here and a leading period on |
| a hostname doesn't make sense |
| so we'll just reject this. */ |
| { "*", "foo.example.com", FALSE }, /* wildcard must be left-most label, |
| implies that there must be more than |
| one label. */ |
| { "*", "example.com", FALSE }, |
| { "*", "com", FALSE }, |
| { "*.example.com", "foo.example.net", FALSE }, /* difference in literal text |
| with a wildcard. */ |
| { "*.com", "example.com", TRUE }, /* See Errata ID 3090 for RFC 6125, |
| probably shouldn't allow this but |
| we do for now. */ |
| { "*.", "example.com", FALSE }, /* test some dubious 2 character wildcard |
| patterns */ |
| { "*.", "example.", TRUE }, /* This one feels questionable */ |
| { "*.", "example", FALSE }, |
| { "*.", ".", FALSE }, |
| { "a", "a", TRUE }, /* check that single letter exact matches work */ |
| { "a", "b", FALSE }, /* and single letter not matches shouldn't */ |
| { "*.*.com", "foo.example.com", FALSE }, /* unsupported wildcards */ |
| { "*.*.com", "example.com", FALSE }, |
| { "**.example.com", "foo.example.com", FALSE }, |
| { "**.example.com", "example.com", FALSE }, |
| { "f*.example.com", "foo.example.com", FALSE }, |
| { "f*.example.com", "bar.example.com", FALSE }, |
| { "*o.example.com", "foo.example.com", FALSE }, |
| { "*o.example.com", "bar.example.com", FALSE }, |
| { "f*o.example.com", "foo.example.com", FALSE }, |
| { "f*o.example.com", "bar.example.com", FALSE }, |
| { "foo.e*.com", "foo.example.com", FALSE }, |
| { "foo.*e.com", "foo.example.com", FALSE }, |
| { "foo.e*e.com", "foo.example.com", FALSE }, |
| { "foo.example.com", "foo.example.com.", TRUE }, /* trailing dot */ |
| { "*.example.com", "foo.example.com.", TRUE }, |
| { "foo", "foo.", TRUE }, |
| { "foo.example.com.", "foo.example.com", FALSE }, |
| { "*.example.com.", "foo.example.com", FALSE }, |
| { "foo.", "foo", FALSE }, |
| { "foo.example.com", "foo.example.com..", FALSE }, |
| { "*.example.com", "foo.example.com..", FALSE }, |
| { "foo", "foo..", FALSE }, |
| { "foo.example.com..", "foo.example.com", FALSE }, |
| { "*.example.com..", "foo.example.com", FALSE }, |
| { "foo..", "foo", FALSE }, |
| { NULL } |
| }; |
| |
| static svn_error_t * |
| test_cert_match_dns_identity(apr_pool_t *pool) |
| { |
| return run_cert_match_dns_tests(cert_match_dns_tests, pool); |
| } |
| |
| /* This test table implements results that should happen if we supported |
| * RFC 6125 s. 6.4.3 Rule 3. We don't so it's expected to fail for now. */ |
| static struct cert_match_dns_test rule3_tests[] = { |
| { "baz*.example.net", "baz1.example.net", TRUE }, |
| { "*baz.example.net", "foobaz.example.net", TRUE }, |
| { "b*z.example.net", "buuz.example.net", TRUE }, |
| { "b*z.example.net", "bz.example.net", FALSE }, /* presume wildcard can't |
| match nothing */ |
| { "baz*.example.net", "baz.example.net", FALSE }, |
| { "*baz.example.net", "baz.example.net", FALSE }, |
| { "b*z.example.net", "buuzuuz.example.net", TRUE }, /* presume wildcard |
| should be greedy */ |
| { NULL } |
| }; |
| |
| static svn_error_t * |
| test_rule3(apr_pool_t *pool) |
| { |
| return run_cert_match_dns_tests(rule3_tests, pool); |
| } |
| |
| |
| /* The test table. */ |
| |
| static int max_threads = 1; |
| |
| static struct svn_test_descriptor_t test_funcs[] = |
| { |
| SVN_TEST_NULL, |
| SVN_TEST_PASS2(test_dirent_is_root, |
| "test svn_dirent_is_root"), |
| SVN_TEST_PASS2(test_uri_is_root, |
| "test svn_uri_is_root"), |
| SVN_TEST_PASS2(test_dirent_is_absolute, |
| "test svn_dirent_is_absolute"), |
| SVN_TEST_PASS2(test_dirent_join, |
| "test svn_dirent_join(_many)"), |
| SVN_TEST_PASS2(test_relpath_join, |
| "test svn_relpath_join"), |
| SVN_TEST_PASS2(test_dirent_basename, |
| "test svn_dirent_basename"), |
| SVN_TEST_PASS2(test_relpath_basename, |
| "test svn_relpath_basename"), |
| SVN_TEST_PASS2(test_uri_basename, |
| "test svn_uri_basename"), |
| SVN_TEST_PASS2(test_relpath_dirname, |
| "test svn_relpath_dirname"), |
| SVN_TEST_PASS2(test_dirent_dirname, |
| "test svn_dirent_dirname"), |
| SVN_TEST_PASS2(test_uri_dirname, |
| "test svn_dirent_dirname"), |
| SVN_TEST_PASS2(test_dirent_canonicalize, |
| "test svn_dirent_canonicalize"), |
| SVN_TEST_PASS2(test_relpath_canonicalize, |
| "test svn_relpath_canonicalize"), |
| SVN_TEST_PASS2(test_uri_canonicalize, |
| "test svn_uri_canonicalize"), |
| SVN_TEST_PASS2(test_dirent_is_canonical, |
| "test svn_dirent_is_canonical"), |
| SVN_TEST_PASS2(test_relpath_is_canonical, |
| "test svn_relpath_is_canonical"), |
| SVN_TEST_PASS2(test_uri_is_canonical, |
| "test svn_uri_is_canonical"), |
| SVN_TEST_PASS2(test_dirent_split, |
| "test svn_dirent_split"), |
| SVN_TEST_PASS2(test_relpath_split, |
| "test svn_relpath_split"), |
| SVN_TEST_PASS2(test_uri_split, |
| "test svn_uri_split"), |
| SVN_TEST_PASS2(test_dirent_get_longest_ancestor, |
| "test svn_dirent_get_longest_ancestor"), |
| SVN_TEST_PASS2(test_relpath_get_longest_ancestor, |
| "test svn_relpath_get_longest_ancestor"), |
| SVN_TEST_PASS2(test_uri_get_longest_ancestor, |
| "test svn_uri_get_longest_ancestor"), |
| SVN_TEST_PASS2(test_dirent_is_child, |
| "test svn_dirent_is_child"), |
| SVN_TEST_PASS2(test_dirent_is_ancestor, |
| "test svn_dirent_is_ancestor"), |
| SVN_TEST_PASS2(test_uri_is_ancestor, |
| "test svn_uri_is_ancestor"), |
| SVN_TEST_PASS2(test_dirent_skip_ancestor, |
| "test svn_dirent_skip_ancestor"), |
| SVN_TEST_PASS2(test_relpath_skip_ancestor, |
| "test svn_relpath_skip_ancestor"), |
| SVN_TEST_PASS2(test_uri_skip_ancestor, |
| "test svn_uri_skip_ancestor"), |
| SVN_TEST_PASS2(test_dirent_get_absolute, |
| "test svn_dirent_get_absolute"), |
| #ifdef WIN32 |
| SVN_TEST_PASS2(test_dirent_get_absolute_from_lc_drive, |
| "test svn_dirent_get_absolute (needs recent apr)"), |
| #endif |
| SVN_TEST_PASS2(test_dirent_condense_targets, |
| "test svn_dirent_condense_targets"), |
| SVN_TEST_PASS2(test_uri_condense_targets, |
| "test svn_uri_condense_targets"), |
| SVN_TEST_PASS2(test_dirent_local_style, |
| "test svn_dirent_local_style"), |
| SVN_TEST_PASS2(test_dirent_internal_style, |
| "test svn_dirent_internal_style"), |
| SVN_TEST_PASS2(test_relpath_internal_style, |
| "test svn_relpath_internal_style"), |
| SVN_TEST_PASS2(test_dirent_from_file_url, |
| "test svn_uri_get_dirent_from_file_url"), |
| SVN_TEST_PASS2(test_dirent_from_file_url_errors, |
| "test svn_uri_get_dirent_from_file_url errors"), |
| SVN_TEST_PASS2(test_file_url_from_dirent, |
| "test svn_uri_get_file_url_from_dirent"), |
| SVN_TEST_PASS2(test_dirent_is_under_root, |
| "test svn_dirent_is_under_root"), |
| SVN_TEST_PASS2(test_fspath_is_canonical, |
| "test svn_fspath__is_canonical"), |
| SVN_TEST_PASS2(test_fspath_join, |
| "test svn_fspath__join"), |
| SVN_TEST_PASS2(test_fspath_skip_ancestor, |
| "test svn_fspath__skip_ancestor"), |
| SVN_TEST_PASS2(test_fspath_dirname_basename_split, |
| "test svn_fspath__dirname/basename/split"), |
| SVN_TEST_PASS2(test_fspath_get_longest_ancestor, |
| "test svn_fspath__get_longest_ancestor"), |
| SVN_TEST_PASS2(test_cert_match_dns_identity, |
| "test svn_cert__match_dns_identity"), |
| SVN_TEST_XFAIL2(test_rule3, |
| "test match with RFC 6125 s. 6.4.3 Rule 3"), |
| SVN_TEST_NULL |
| }; |
| |
| SVN_TEST_MAIN |