From fb2e0b50c8dc4149809cd9b917c8b43578683c27 Mon Sep 17 00:00:00 2001 From: Christian Prochaska Date: Wed, 7 Feb 2024 13:58:39 +0100 Subject: [PATCH] os: 'Path_base::strip_double_dot_dirs()' improvements Issue #5106 --- repos/os/include/os/path.h | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/repos/os/include/os/path.h b/repos/os/include/os/path.h index 39877dde5c..6880fb0f47 100644 --- a/repos/os/include/os/path.h +++ b/repos/os/include/os/path.h @@ -130,6 +130,12 @@ class Genode::Path_base static void strip_double_dot_dirs(char *path) { + bool path_was_absolute = absolute(path); + + /* + * Strip any occurrence of "/.." and the previous path + * element (including leading slash) if one exists. + */ unsigned i; while ((i = find_double_dot_dir(path))) { @@ -141,12 +147,27 @@ class Genode::Path_base while (cut_start > 0 && path[cut_start - 1] != '/') cut_start--; - /* skip slash in front of the pair of dots */ + /* skip slash in front of the previous path element */ if (cut_start > 0) cut_start--; strip(path + cut_start, cut_end - cut_start); } + + if (path_was_absolute) { + /* restore the leading slash if it got stripped */ + if (empty(path)) + copy_cstring(path, "/", 2); + } else { + /* remove leading ".." if present */ + if (path[0] == '.' && path[1] == '.' + && (path[2] == 0 || path[2] == '/')) + strip(path, 2); + + /* remove leading slash if one is present now */ + if (path[0] == '/') + strip(path, 1); + } } private: