mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-14 01:40:30 +01:00
glib-aux: add path-utils from systemd
We use these functions, currently from our systemd fork. One day we want to stop importing systemd code, so we need them ourselves. Copy them, and adjust for NM style.
This commit is contained in:
parent
82cac62fe2
commit
b5f3d88e6f
3 changed files with 585 additions and 0 deletions
|
|
@ -6933,3 +6933,245 @@ on_failure:
|
|||
nm_explicit_bzero(buf, len);
|
||||
return r;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const char *
|
||||
skip_slash_or_dot(const char *p)
|
||||
{
|
||||
for (; !nm_str_is_empty(p);) {
|
||||
if (p[0] == '/') {
|
||||
p += 1;
|
||||
continue;
|
||||
}
|
||||
if (p[0] == '.' && p[1] == '/') {
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
nm_path_find_first_component(const char **p, gboolean accept_dot_dot, const char **ret)
|
||||
{
|
||||
const char *q, *first, *end_first, *next;
|
||||
size_t len;
|
||||
|
||||
/* Copied from systemd's path_compare()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L809 */
|
||||
|
||||
nm_assert(p);
|
||||
|
||||
/* When a path is input, then returns the pointer to the first component and its length, and
|
||||
* move the input pointer to the next component or nul. This skips both over any '/'
|
||||
* immediately *before* and *after* the first component before returning.
|
||||
*
|
||||
* Examples
|
||||
* Input: p: "//.//aaa///bbbbb/cc"
|
||||
* Output: p: "bbbbb///cc"
|
||||
* ret: "aaa///bbbbb/cc"
|
||||
* return value: 3 (== strlen("aaa"))
|
||||
*
|
||||
* Input: p: "aaa//"
|
||||
* Output: p: (pointer to NUL)
|
||||
* ret: "aaa//"
|
||||
* return value: 3 (== strlen("aaa"))
|
||||
*
|
||||
* Input: p: "/", ".", ""
|
||||
* Output: p: (pointer to NUL)
|
||||
* ret: NULL
|
||||
* return value: 0
|
||||
*
|
||||
* Input: p: NULL
|
||||
* Output: p: NULL
|
||||
* ret: NULL
|
||||
* return value: 0
|
||||
*
|
||||
* Input: p: "(too long component)"
|
||||
* Output: return value: -EINVAL
|
||||
*
|
||||
* (when accept_dot_dot is false)
|
||||
* Input: p: "//..//aaa///bbbbb/cc"
|
||||
* Output: return value: -EINVAL
|
||||
*/
|
||||
|
||||
q = *p;
|
||||
|
||||
first = skip_slash_or_dot(q);
|
||||
if (nm_str_is_empty(first)) {
|
||||
*p = first;
|
||||
if (ret)
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (nm_streq(first, ".")) {
|
||||
*p = first + 1;
|
||||
if (ret)
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
end_first = strchrnul(first, '/');
|
||||
len = end_first - first;
|
||||
|
||||
if (len > NAME_MAX)
|
||||
return -EINVAL;
|
||||
if (!accept_dot_dot && len == 2 && first[0] == '.' && first[1] == '.')
|
||||
return -EINVAL;
|
||||
|
||||
next = skip_slash_or_dot(end_first);
|
||||
|
||||
*p = next + (nm_streq(next, ".") ? 1 : 0);
|
||||
if (ret)
|
||||
*ret = first;
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
nm_path_compare(const char *a, const char *b)
|
||||
{
|
||||
/* Copied from systemd's path_compare()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L415 */
|
||||
|
||||
/* Order NULL before non-NULL */
|
||||
NM_CMP_SELF(a, b);
|
||||
|
||||
/* A relative path and an absolute path must not compare as equal.
|
||||
* Which one is sorted before the other does not really matter.
|
||||
* Here a relative path is ordered before an absolute path. */
|
||||
NM_CMP_DIRECT(nm_path_is_absolute(a), nm_path_is_absolute(b));
|
||||
|
||||
for (;;) {
|
||||
const char *aa, *bb;
|
||||
int j, k;
|
||||
|
||||
j = nm_path_find_first_component(&a, TRUE, &aa);
|
||||
k = nm_path_find_first_component(&b, TRUE, &bb);
|
||||
|
||||
if (j < 0 || k < 0) {
|
||||
/* When one of paths is invalid, order invalid path after valid one. */
|
||||
NM_CMP_DIRECT(j < 0, k < 0);
|
||||
|
||||
/* fallback to use strcmp() if both paths are invalid. */
|
||||
NM_CMP_DIRECT_STRCMP(a, b);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Order prefixes first: "/foo" before "/foo/bar" */
|
||||
if (j == 0) {
|
||||
if (k == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
if (k == 0)
|
||||
return 1;
|
||||
|
||||
/* Alphabetical sort: "/foo/aaa" before "/foo/b" */
|
||||
NM_CMP_DIRECT_MEMCMP(aa, bb, NM_MIN(j, k));
|
||||
|
||||
/* Sort "/foo/a" before "/foo/aaa" */
|
||||
NM_CMP_DIRECT(j, k);
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
nm_path_startswith_full(const char *path, const char *prefix, gboolean accept_dot_dot)
|
||||
{
|
||||
/* Copied from systemd's path_startswith_full()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L375 */
|
||||
|
||||
nm_assert(path);
|
||||
nm_assert(prefix);
|
||||
|
||||
/* Returns a pointer to the start of the first component after the parts matched by
|
||||
* the prefix, iff
|
||||
* - both paths are absolute or both paths are relative,
|
||||
* and
|
||||
* - each component in prefix in turn matches a component in path at the same position.
|
||||
* An empty string will be returned when the prefix and path are equivalent.
|
||||
*
|
||||
* Returns NULL otherwise.
|
||||
*/
|
||||
|
||||
if ((path[0] == '/') != (prefix[0] == '/'))
|
||||
return NULL;
|
||||
|
||||
for (;;) {
|
||||
const char *p, *q;
|
||||
int r, k;
|
||||
|
||||
r = nm_path_find_first_component(&path, accept_dot_dot, &p);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
k = nm_path_find_first_component(&prefix, accept_dot_dot, &q);
|
||||
if (k < 0)
|
||||
return NULL;
|
||||
|
||||
if (k == 0)
|
||||
return (char *) (p ?: path);
|
||||
|
||||
if (r != k)
|
||||
return NULL;
|
||||
|
||||
if (strncmp(p, q, r) != 0)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
nm_path_simplify(char *path)
|
||||
{
|
||||
bool add_slash = false;
|
||||
char *f = path;
|
||||
int r;
|
||||
|
||||
/* Copied from systemd's path_simplify()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.c#L325 */
|
||||
|
||||
nm_assert(path);
|
||||
|
||||
/* Removes redundant inner and trailing slashes. Also removes unnecessary dots.
|
||||
* Modifies the passed string in-place.
|
||||
*
|
||||
* ///foo//./bar/. becomes /foo/bar
|
||||
* .//./foo//./bar/. becomes foo/bar
|
||||
*/
|
||||
|
||||
if (path[0] == '\0')
|
||||
return path;
|
||||
|
||||
if (nm_path_is_absolute(path))
|
||||
f++;
|
||||
|
||||
for (const char *p = f;;) {
|
||||
const char *e;
|
||||
|
||||
r = nm_path_find_first_component(&p, TRUE, &e);
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (add_slash)
|
||||
*f++ = '/';
|
||||
|
||||
if (r < 0) {
|
||||
/* if path is invalid, then refuse to simplify remaining part. */
|
||||
memmove(f, p, strlen(p) + 1);
|
||||
return path;
|
||||
}
|
||||
|
||||
memmove(f, e, r);
|
||||
f += r;
|
||||
|
||||
add_slash = TRUE;
|
||||
}
|
||||
|
||||
/* Special rule, if we stripped everything, we need a "." for the current directory. */
|
||||
if (f == path)
|
||||
*f++ = '.';
|
||||
|
||||
*f = '\0';
|
||||
return path;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3313,4 +3313,37 @@ void nm_utils_thread_local_register_destroy(gpointer tls_data, GDestroyNotify de
|
|||
int nm_unbase64char(char c);
|
||||
int nm_unbase64mem_full(const char *p, gsize l, gboolean secure, guint8 **ret, gsize *ret_size);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static inline gboolean
|
||||
nm_path_is_absolute(const char *p)
|
||||
{
|
||||
/* Copied from systemd's path_is_absolute()
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/basic/path-util.h#L50 */
|
||||
|
||||
nm_assert(p);
|
||||
return p[0] == '/';
|
||||
}
|
||||
|
||||
int nm_path_find_first_component(const char **p, gboolean accept_dot_dot, const char **ret);
|
||||
|
||||
int nm_path_compare(const char *a, const char *b);
|
||||
|
||||
static inline gboolean
|
||||
nm_path_equal(const char *a, const char *b)
|
||||
{
|
||||
return nm_path_compare(a, b) == 0;
|
||||
}
|
||||
|
||||
char *nm_path_simplify(char *path);
|
||||
|
||||
char *
|
||||
nm_path_startswith_full(const char *path, const char *prefix, gboolean accept_dot_dot) _nm_pure;
|
||||
|
||||
static inline char *
|
||||
nm_path_startswith(const char *path, const char *prefix)
|
||||
{
|
||||
return nm_path_startswith_full(path, prefix, TRUE);
|
||||
}
|
||||
|
||||
#endif /* __NM_SHARED_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -1796,6 +1796,311 @@ test_unbase64mem3(void)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_compare(const char *a, const char *b, int expected)
|
||||
{
|
||||
int r;
|
||||
|
||||
g_assert(NM_IN_SET(expected, -1, 0, 1));
|
||||
|
||||
g_assert_cmpint(nm_path_compare(a, a), ==, 0);
|
||||
g_assert_cmpint(nm_path_compare(b, b), ==, 0);
|
||||
|
||||
r = nm_path_compare(a, b);
|
||||
g_assert_cmpint(r, ==, expected);
|
||||
r = nm_path_compare(b, a);
|
||||
g_assert_cmpint(r, ==, -expected);
|
||||
|
||||
g_assert(nm_path_equal(a, a) == 1);
|
||||
g_assert(nm_path_equal(b, b) == 1);
|
||||
g_assert(nm_path_equal(a, b) == (expected == 0));
|
||||
g_assert(nm_path_equal(b, a) == (expected == 0));
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_compare(void)
|
||||
{
|
||||
/* Copied from systemd.
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/test/test-path-util.c#L126 */
|
||||
|
||||
assert_path_compare("/goo", "/goo", 0);
|
||||
assert_path_compare("/goo", "/goo", 0);
|
||||
assert_path_compare("//goo", "/goo", 0);
|
||||
assert_path_compare("//goo/////", "/goo", 0);
|
||||
assert_path_compare("goo/////", "goo", 0);
|
||||
assert_path_compare("/goo/boo", "/goo//boo", 0);
|
||||
assert_path_compare("//goo/boo", "/goo/boo//", 0);
|
||||
assert_path_compare("//goo/././//./boo//././//", "/goo/boo//.", 0);
|
||||
assert_path_compare("/.", "//.///", 0);
|
||||
assert_path_compare("/x", "x/", 1);
|
||||
assert_path_compare("x/", "/", -1);
|
||||
assert_path_compare("/x/./y", "x/y", 1);
|
||||
assert_path_compare("/x/./y", "/x/y", 0);
|
||||
assert_path_compare("/x/./././y", "/x/y/././.", 0);
|
||||
assert_path_compare("./x/./././y", "./x/y/././.", 0);
|
||||
assert_path_compare(".", "./.", 0);
|
||||
assert_path_compare(".", "././.", 0);
|
||||
assert_path_compare("./..", ".", 1);
|
||||
assert_path_compare("x/.y", "x/y", -1);
|
||||
assert_path_compare("foo", "/foo", -1);
|
||||
assert_path_compare("/foo", "/foo/bar", -1);
|
||||
assert_path_compare("/foo/aaa", "/foo/b", -1);
|
||||
assert_path_compare("/foo/aaa", "/foo/b/a", -1);
|
||||
assert_path_compare("/foo/a", "/foo/aaa", -1);
|
||||
assert_path_compare("/foo/a/b", "/foo/aaa", -1);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
test_path_equal(void)
|
||||
{
|
||||
#define _path_equal_check(path, expected) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
const char *_path0 = (path); \
|
||||
const char *_expected = (expected); \
|
||||
gs_free char *_path = g_strdup(_path0); \
|
||||
const char *_path_result; \
|
||||
\
|
||||
_path_result = nm_path_simplify(_path); \
|
||||
g_assert(_path_result == _path); \
|
||||
g_assert_cmpstr(_path, ==, _expected); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
_path_equal_check("", "");
|
||||
_path_equal_check(".", ".");
|
||||
_path_equal_check("..", "..");
|
||||
_path_equal_check("/..", "/..");
|
||||
_path_equal_check("//..", "/..");
|
||||
_path_equal_check("/.", "/");
|
||||
_path_equal_check("./", ".");
|
||||
_path_equal_check("./.", ".");
|
||||
_path_equal_check(".///.", ".");
|
||||
_path_equal_check(".///./", ".");
|
||||
_path_equal_check(".////", ".");
|
||||
_path_equal_check("//..//foo/", "/../foo");
|
||||
_path_equal_check("///foo//./bar/.", "/foo/bar");
|
||||
_path_equal_check(".//./foo//./bar/.", "foo/bar");
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_find_first_component(const char *path,
|
||||
gboolean accept_dot_dot,
|
||||
const char *const *expected,
|
||||
int ret)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
for (p = path;;) {
|
||||
const char *e;
|
||||
int r;
|
||||
|
||||
r = nm_path_find_first_component(&p, accept_dot_dot, &e);
|
||||
if (r <= 0) {
|
||||
if (r == 0) {
|
||||
if (path)
|
||||
g_assert(p == path + strlen(path));
|
||||
else
|
||||
g_assert(!p);
|
||||
g_assert(!e);
|
||||
}
|
||||
g_assert(r == ret);
|
||||
g_assert(!expected || !*expected);
|
||||
return;
|
||||
}
|
||||
|
||||
g_assert(e);
|
||||
g_assert(strcspn(e, "/") == (size_t) r);
|
||||
g_assert(strlen(*expected) == (size_t) r);
|
||||
g_assert(strncmp(e, *expected++, r) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_find_first_component(void)
|
||||
{
|
||||
gs_free char *hoge = NULL;
|
||||
char foo[NAME_MAX * 2];
|
||||
|
||||
/* Copied from systemd.
|
||||
* https://github.com/systemd/systemd/blob/bc85f8b51d962597360e982811e674c126850f56/src/test/test-path-util.c#L631 */
|
||||
|
||||
assert_path_find_first_component(NULL, false, NULL, 0);
|
||||
assert_path_find_first_component("", false, NULL, 0);
|
||||
assert_path_find_first_component("/", false, NULL, 0);
|
||||
assert_path_find_first_component(".", false, NULL, 0);
|
||||
assert_path_find_first_component("./", false, NULL, 0);
|
||||
assert_path_find_first_component("./.", false, NULL, 0);
|
||||
assert_path_find_first_component("..", false, NULL, -EINVAL);
|
||||
assert_path_find_first_component("/..", false, NULL, -EINVAL);
|
||||
assert_path_find_first_component("./..", false, NULL, -EINVAL);
|
||||
assert_path_find_first_component("////./././//.", false, NULL, 0);
|
||||
assert_path_find_first_component("a/b/c", false, NM_MAKE_STRV("a", "b", "c"), 0);
|
||||
assert_path_find_first_component("././//.///aa/bbb//./ccc",
|
||||
false,
|
||||
NM_MAKE_STRV("aa", "bbb", "ccc"),
|
||||
0);
|
||||
assert_path_find_first_component("././//.///aa/.../../bbb//./ccc/.",
|
||||
false,
|
||||
NM_MAKE_STRV("aa", "..."),
|
||||
-EINVAL);
|
||||
assert_path_find_first_component("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
|
||||
false,
|
||||
NM_MAKE_STRV("aaa", ".bbb"),
|
||||
-EINVAL);
|
||||
assert_path_find_first_component("a/foo./b", false, NM_MAKE_STRV("a", "foo.", "b"), 0);
|
||||
|
||||
assert_path_find_first_component(NULL, true, NULL, 0);
|
||||
assert_path_find_first_component("", true, NULL, 0);
|
||||
assert_path_find_first_component("/", true, NULL, 0);
|
||||
assert_path_find_first_component(".", true, NULL, 0);
|
||||
assert_path_find_first_component("./", true, NULL, 0);
|
||||
assert_path_find_first_component("./.", true, NULL, 0);
|
||||
assert_path_find_first_component("..", true, NM_MAKE_STRV(".."), 0);
|
||||
assert_path_find_first_component("/..", true, NM_MAKE_STRV(".."), 0);
|
||||
assert_path_find_first_component("./..", true, NM_MAKE_STRV(".."), 0);
|
||||
assert_path_find_first_component("////./././//.", true, NULL, 0);
|
||||
assert_path_find_first_component("a/b/c", true, NM_MAKE_STRV("a", "b", "c"), 0);
|
||||
assert_path_find_first_component("././//.///aa/bbb//./ccc",
|
||||
true,
|
||||
NM_MAKE_STRV("aa", "bbb", "ccc"),
|
||||
0);
|
||||
assert_path_find_first_component("././//.///aa/.../../bbb//./ccc/.",
|
||||
true,
|
||||
NM_MAKE_STRV("aa", "...", "..", "bbb", "ccc"),
|
||||
0);
|
||||
assert_path_find_first_component("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
|
||||
true,
|
||||
NM_MAKE_STRV("aaa", ".bbb", "..", "c.", "d.dd", "..eeee"),
|
||||
0);
|
||||
assert_path_find_first_component("a/foo./b", true, NM_MAKE_STRV("a", "foo.", "b"), 0);
|
||||
|
||||
memset(foo, 'a', sizeof(foo) - 1);
|
||||
foo[sizeof(foo) - 1] = '\0';
|
||||
|
||||
assert_path_find_first_component(foo, false, NULL, -EINVAL);
|
||||
assert_path_find_first_component(foo, true, NULL, -EINVAL);
|
||||
|
||||
hoge = g_strjoin("", "a/b/c/", foo, "//d/e/.//f/", NULL);
|
||||
g_assert(hoge);
|
||||
|
||||
assert_path_find_first_component(hoge, false, NM_MAKE_STRV("a", "b", "c"), -EINVAL);
|
||||
assert_path_find_first_component(hoge, true, NM_MAKE_STRV("a", "b", "c"), -EINVAL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_startswith(const char *path,
|
||||
const char *prefix,
|
||||
const char *skipped,
|
||||
const char *expected)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = nm_path_startswith(path, prefix);
|
||||
g_assert_cmpstr(p, ==, expected);
|
||||
if (p) {
|
||||
gs_free char *q = NULL;
|
||||
|
||||
g_assert(skipped);
|
||||
q = g_strjoin("", skipped, p, NULL);
|
||||
g_assert_cmpstr(q, ==, path);
|
||||
g_assert(p == path + strlen(skipped));
|
||||
} else
|
||||
g_assert(!skipped);
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_startswith(void)
|
||||
{
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo", "/foo/", "bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/", "/foo/", "bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/", "/", "foo/bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "////", "/", "foo/bar/barfoo/");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/", "/foo/bar/barfoo/", "");
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo", "/foo/bar/barfoo/", "");
|
||||
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/bar/foo", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/f/b/b/", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/barfo", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/foo/bar/bar", NULL, NULL);
|
||||
assert_path_startswith("/foo/bar/barfoo/", "/fo", NULL, NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
assert_path_simplify(const char *in, const char *out)
|
||||
{
|
||||
gs_free char *p = NULL;
|
||||
|
||||
g_assert(in);
|
||||
p = g_strdup(in);
|
||||
nm_path_simplify(p);
|
||||
g_assert_cmpstr(p, ==, out);
|
||||
}
|
||||
|
||||
static void
|
||||
test_path_simplify(void)
|
||||
{
|
||||
gs_free char *hoge = NULL;
|
||||
gs_free char *hoge_out = NULL;
|
||||
char foo[NAME_MAX * 2];
|
||||
|
||||
assert_path_simplify("", "");
|
||||
assert_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc");
|
||||
assert_path_simplify("//aaa/.////ccc", "/aaa/ccc");
|
||||
assert_path_simplify("///", "/");
|
||||
assert_path_simplify("///.//", "/");
|
||||
assert_path_simplify("///.//.///", "/");
|
||||
assert_path_simplify("////.././///../.", "/../..");
|
||||
assert_path_simplify(".", ".");
|
||||
assert_path_simplify("./", ".");
|
||||
assert_path_simplify(".///.//./.", ".");
|
||||
assert_path_simplify(".///.//././/", ".");
|
||||
assert_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
|
||||
"/aaa/.bbb/../c./d.dd/..eeee");
|
||||
assert_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||
"/aaa/.bbb/../c./d.dd/..eeee/..");
|
||||
assert_path_simplify(".//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||
"aaa/.bbb/../c./d.dd/..eeee/..");
|
||||
assert_path_simplify("..//./aaa///.//./.bbb/..///c.//d.dd///..eeee/..",
|
||||
"../aaa/.bbb/../c./d.dd/..eeee/..");
|
||||
|
||||
memset(foo, 'a', sizeof(foo) - 1);
|
||||
foo[sizeof(foo) - 1] = '\0';
|
||||
|
||||
assert_path_simplify(foo, foo);
|
||||
|
||||
hoge = g_strjoin("", "/", foo, NULL);
|
||||
g_assert(hoge);
|
||||
assert_path_simplify(hoge, hoge);
|
||||
nm_clear_g_free(&hoge);
|
||||
|
||||
hoge =
|
||||
g_strjoin("", "a////.//././//./b///././/./c/////././//./", foo, "//.//////d/e/.//f/", NULL);
|
||||
g_assert(hoge);
|
||||
|
||||
hoge_out = g_strjoin("", "a/b/c/", foo, "//.//////d/e/.//f/", NULL);
|
||||
g_assert(hoge_out);
|
||||
|
||||
assert_path_simplify(hoge, hoge_out);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE();
|
||||
|
||||
int
|
||||
|
|
@ -1834,6 +2139,11 @@ main(int argc, char **argv)
|
|||
g_test_add_func("/general/test_unbase64mem1", test_unbase64mem1);
|
||||
g_test_add_func("/general/test_unbase64mem2", test_unbase64mem2);
|
||||
g_test_add_func("/general/test_unbase64mem3", test_unbase64mem3);
|
||||
g_test_add_func("/general/test_path_compare", test_path_compare);
|
||||
g_test_add_func("/general/test_path_equal", test_path_equal);
|
||||
g_test_add_func("/general/test_path_find_first_component", test_path_find_first_component);
|
||||
g_test_add_func("/general/test_path_startswith", test_path_startswith);
|
||||
g_test_add_func("/general/test_path_simplify", test_path_simplify);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue