diff options
author | Thomas Haller <thaller@redhat.com> | 2018-10-05 11:40:50 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-10-23 10:32:53 +0200 |
commit | 9dce4a426ba82307cd27de23f3f3d8aed569d79b (patch) | |
tree | ca513a95ae2dae9ba93025f6fd4343c829748b32 | |
parent | eece5aff0992c9076a9b5513e2a893e37e4999ea (diff) | |
download | NetworkManager-9dce4a426ba82307cd27de23f3f3d8aed569d79b.tar.gz |
systemd: fix handling special cases kill_dots and path_simplify()
Previously, paths like ".", "./", ./." would all result in an
empty path. That is wrong, one dot must be kept.
https://github.com/systemd/systemd/commit/afbae3e9f23dc6682d48a1cc3585e8429ef07d8b
-rw-r--r-- | src/systemd/src/basic/path-util.c | 22 | ||||
-rw-r--r-- | src/tests/test-systemd.c | 12 |
2 files changed, 21 insertions, 13 deletions
diff --git a/src/systemd/src/basic/path-util.c b/src/systemd/src/basic/path-util.c index b758c34d0c..5877957822 100644 --- a/src/systemd/src/basic/path-util.c +++ b/src/systemd/src/basic/path-util.c @@ -337,12 +337,15 @@ char *path_simplify(char *path, bool kill_dots) { /* Removes redundant inner and trailing slashes. Also removes unnecessary dots * if kill_dots is true. Modifies the passed string in-place. * - * ///foo//./bar/. becomes /foo/./bar/. (if kill_dots is false) - * ///foo//./bar/. becomes /foo/bar (if kill_dots is true) - * .//./foo//./bar/. becomes ./foo/bar (if kill_dots is false) - * .//./foo//./bar/. becomes foo/bar (if kill_dots is true) + * ///foo//./bar/. becomes /foo/./bar/. (if kill_dots is false) + * ///foo//./bar/. becomes /foo/bar (if kill_dots is true) + * .//./foo//./bar/. becomes ././foo/./bar/. (if kill_dots is false) + * .//./foo//./bar/. becomes foo/bar (if kill_dots is true) */ + if (isempty(path)) + return path; + absolute = path_is_absolute(path); f = path; @@ -372,9 +375,14 @@ char *path_simplify(char *path, bool kill_dots) { *(t++) = *f; } - /* Special rule, if we are talking of the root directory, a trailing slash is good */ - if (absolute && t == path) - *(t++) = '/'; + /* Special rule, if we stripped everything, we either need a "/" (for the root directory) + * or "." for the current directory */ + if (t == path) { + if (absolute) + *(t++) = '/'; + else + *(t++) = '.'; + } *t = 0; return path; diff --git a/src/tests/test-systemd.c b/src/tests/test-systemd.c index 4660bd0d17..6015e9df07 100644 --- a/src/tests/test-systemd.c +++ b/src/tests/test-systemd.c @@ -201,16 +201,16 @@ test_path_equal (void) } G_STMT_END _path_equal_check ("", "", NULL); - _path_equal_check (".", ".", ""); + _path_equal_check (".", ".", NULL); _path_equal_check ("..", "..", NULL); _path_equal_check ("/..", "/..", NULL); _path_equal_check ("//..", "/..", NULL); _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", NULL); _path_equal_check ("///foo//./bar/.", "/foo/./bar/.", "/foo/bar"); _path_equal_check (".//./foo//./bar/.", "././foo/./bar/.", "foo/bar"); |