From 321384507f1223033fc0fb2969f6e29598ba7d92 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 2 Feb 2017 00:06:18 +0100 Subject: [PATCH] fs-util: unify code we use to check if dirent's d_name is "." or ".." We use different idioms at different places. Let's replace this is the one true new idiom, that is even a bit faster... --- src/basic/cgroup-util.c | 3 +-- src/basic/copy.c | 2 +- src/basic/path-util.c | 25 +++++++++++++++++++------ src/basic/path-util.h | 2 ++ src/basic/rm-rf.c | 2 +- src/basic/socket-util.c | 2 +- src/shared/clean-ipc.c | 4 ++-- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index 0e2f2cbc0..32cf4298f 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -184,8 +184,7 @@ int cg_read_subgroup(DIR *d, char **fn) { if (de->d_type != DT_DIR) continue; - if (streq(de->d_name, ".") || - streq(de->d_name, "..")) + if (dot_or_dot_dot(de->d_name)) continue; b = strdup(de->d_name); diff --git a/src/basic/copy.c b/src/basic/copy.c index 4e5f392fe..20078a81e 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -333,7 +333,7 @@ static int fd_copy_directory( struct stat buf; int q; - if (STR_IN_SET(de->d_name, ".", "..")) + if (dot_or_dot_dot(de->d_name)) continue; if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) { diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 84f327d7d..05384c26b 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -703,10 +703,7 @@ bool filename_is_valid(const char *p) { if (isempty(p)) return false; - if (streq(p, ".")) - return false; - - if (streq(p, "..")) + if (dot_or_dot_dot(p)) return false; e = strchrnul(p, '/'); @@ -724,14 +721,17 @@ bool path_is_safe(const char *p) { if (isempty(p)) return false; - if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../")) + if (dot_or_dot_dot(p)) + return false; + + if (startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../")) return false; if (strlen(p)+1 > PATH_MAX) return false; /* The following two checks are not really dangerous, but hey, they still are confusing */ - if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./")) + if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./")) return false; if (strstr(p, "//")) @@ -898,3 +898,16 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version) return false; } #endif // 0 + +bool dot_or_dot_dot(const char *path) { + if (!path) + return false; + if (path[0] != '.') + return false; + if (path[1] == 0) + return true; + if (path[1] != '.') + return false; + + return path[2] == 0; +} diff --git a/src/basic/path-util.h b/src/basic/path-util.h index 6c906e54a..3e1519efe 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -157,3 +157,5 @@ bool is_deviceallow_pattern(const char *path); int systemd_installation_has_version(const char *root, unsigned minimal_version); #endif // 0 + +bool dot_or_dot_dot(const char *path); diff --git a/src/basic/rm-rf.c b/src/basic/rm-rf.c index a90359194..85854acf9 100644 --- a/src/basic/rm-rf.c +++ b/src/basic/rm-rf.c @@ -82,7 +82,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) { bool is_dir; struct stat st; - if (streq(de->d_name, ".") || streq(de->d_name, "..")) + if (dot_or_dot_dot(de->d_name)) continue; if (de->d_type == DT_UNKNOWN || diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 6a8ca1d7e..9ec901261 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -881,7 +881,7 @@ bool ifname_valid(const char *p) { if (strlen(p) >= IFNAMSIZ) return false; - if (STR_IN_SET(p, ".", "..")) + if (dot_or_dot_dot(p)) return false; while (*p) { diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c index ba48fb0ec..3b4231827 100644 --- a/src/shared/clean-ipc.c +++ b/src/shared/clean-ipc.c @@ -225,7 +225,7 @@ static int clean_posix_shm_internal(DIR *dir, uid_t uid, gid_t gid) { FOREACH_DIRENT_ALL(de, dir, goto fail) { struct stat st; - if (STR_IN_SET(de->d_name, "..", ".")) + if (dot_or_dot_dot(de->d_name)) continue; if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { @@ -311,7 +311,7 @@ static int clean_posix_mq(uid_t uid, gid_t gid) { struct stat st; char fn[1+strlen(de->d_name)+1]; - if (STR_IN_SET(de->d_name, "..", ".")) + if (dot_or_dot_dot(de->d_name)) continue; if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { -- 2.30.2