path-util: fix path_simplify() with kill_dots and "."

Previously, together with kill_dots true, patch like
".", "./.", ".//.//" would all return an empty string.

That is wrong. There must be one "." left to reference
the current directory.

Also, the comment with examples was wrong.
This commit is contained in:
Thomas Haller
2018-10-05 13:14:38 +02:00
committed by Lennart Poettering
parent c250bf671b
commit afbae3e9f2
2 changed files with 19 additions and 11 deletions

View File

@@ -333,12 +333,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;
@@ -368,9 +371,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;

View File

@@ -81,10 +81,10 @@ static void test_path(void) {
test_path_simplify("///.//", "/.", "/");
test_path_simplify("///.//.///", "/./.", "/");
test_path_simplify("////.././///../.", "/.././../.", "/../..");
test_path_simplify(".", ".", "");
test_path_simplify("./", ".", "");
test_path_simplify(".///.//./.", "./././.", "");
test_path_simplify(".///.//././/", "./././.", "");
test_path_simplify(".", ".", ".");
test_path_simplify("./", ".", ".");
test_path_simplify(".///.//./.", "./././.", ".");
test_path_simplify(".///.//././/", "./././.", ".");
test_path_simplify("//./aaa///.//./.bbb/..///c.//d.dd///..eeee/.",
"/./aaa/././.bbb/../c./d.dd/..eeee/.",
"/aaa/.bbb/../c./d.dd/..eeee");