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...
This commit is contained in:
Lennart Poettering 2017-02-02 00:06:18 +01:00
parent 1d0106996c
commit 49bfc8774b
12 changed files with 43 additions and 20 deletions

View File

@ -182,8 +182,7 @@ int cg_read_subgroup(DIR *d, char **fn) {
if (de->d_type != DT_DIR) if (de->d_type != DT_DIR)
continue; continue;
if (streq(de->d_name, ".") || if (dot_or_dot_dot(de->d_name))
streq(de->d_name, ".."))
continue; continue;
b = strdup(de->d_name); b = strdup(de->d_name);

View File

@ -331,7 +331,7 @@ static int fd_copy_directory(
struct stat buf; struct stat buf;
int q; int q;
if (STR_IN_SET(de->d_name, ".", "..")) if (dot_or_dot_dot(de->d_name))
continue; continue;
if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) { if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {

View File

@ -699,10 +699,7 @@ bool filename_is_valid(const char *p) {
if (isempty(p)) if (isempty(p))
return false; return false;
if (streq(p, ".")) if (dot_or_dot_dot(p))
return false;
if (streq(p, ".."))
return false; return false;
e = strchrnul(p, '/'); e = strchrnul(p, '/');
@ -720,14 +717,17 @@ bool path_is_safe(const char *p) {
if (isempty(p)) if (isempty(p))
return false; 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; return false;
if (strlen(p)+1 > PATH_MAX) if (strlen(p)+1 > PATH_MAX)
return false; return false;
/* The following two checks are not really dangerous, but hey, they still are confusing */ /* 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; return false;
if (strstr(p, "//")) if (strstr(p, "//"))
@ -892,3 +892,16 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version)
return false; return false;
} }
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;
}

View File

@ -141,3 +141,5 @@ bool is_device_path(const char *path);
bool is_deviceallow_pattern(const char *path); bool is_deviceallow_pattern(const char *path);
int systemd_installation_has_version(const char *root, unsigned minimal_version); int systemd_installation_has_version(const char *root, unsigned minimal_version);
bool dot_or_dot_dot(const char *path);

View File

@ -83,7 +83,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
bool is_dir; bool is_dir;
struct stat st; struct stat st;
if (streq(de->d_name, ".") || streq(de->d_name, "..")) if (dot_or_dot_dot(de->d_name))
continue; continue;
if (de->d_type == DT_UNKNOWN || if (de->d_type == DT_UNKNOWN ||

View File

@ -877,7 +877,7 @@ bool ifname_valid(const char *p) {
if (strlen(p) >= IFNAMSIZ) if (strlen(p) >= IFNAMSIZ)
return false; return false;
if (STR_IN_SET(p, ".", "..")) if (dot_or_dot_dot(p))
return false; return false;
while (*p) { while (*p) {

View File

@ -658,7 +658,7 @@ static int get_block_device_harder(const char *path, dev_t *dev) {
FOREACH_DIRENT_ALL(de, d, return -errno) { FOREACH_DIRENT_ALL(de, d, return -errno) {
if (STR_IN_SET(de->d_name, ".", "..")) if (dot_or_dot_dot(de->d_name))
continue; continue;
if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN)) if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN))

View File

@ -375,7 +375,7 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift
FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) { FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {
struct stat fst; struct stat fst;
if (STR_IN_SET(de->d_name, ".", "..")) if (dot_or_dot_dot(de->d_name))
continue; continue;
if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) { if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) {

View File

@ -1349,7 +1349,7 @@ void manager_cleanup_saved_user(Manager *m) {
if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG)) if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG))
continue; continue;
if (STR_IN_SET(de->d_name, ".", "..")) if (dot_or_dot_dot(de->d_name))
continue; continue;
r = parse_ifindex(de->d_name, &ifindex); r = parse_ifindex(de->d_name, &ifindex);

View File

@ -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) { FOREACH_DIRENT_ALL(de, dir, goto fail) {
struct stat st; struct stat st;
if (STR_IN_SET(de->d_name, "..", ".")) if (dot_or_dot_dot(de->d_name))
continue; continue;
if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
@ -310,7 +310,7 @@ static int clean_posix_mq(uid_t uid, gid_t gid) {
struct stat st; struct stat st;
char fn[1+strlen(de->d_name)+1]; char fn[1+strlen(de->d_name)+1];
if (STR_IN_SET(de->d_name, "..", ".")) if (dot_or_dot_dot(de->d_name))
continue; continue;
if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) { if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {

View File

@ -305,12 +305,23 @@ static void test_var_tmp(void) {
} }
} }
static void test_dot_or_dot_dot(void) {
assert_se(!dot_or_dot_dot(NULL));
assert_se(!dot_or_dot_dot(""));
assert_se(!dot_or_dot_dot("xxx"));
assert_se(dot_or_dot_dot("."));
assert_se(dot_or_dot_dot(".."));
assert_se(!dot_or_dot_dot(".foo"));
assert_se(!dot_or_dot_dot("..foo"));
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
test_unlink_noerrno(); test_unlink_noerrno();
test_readlink_and_make_absolute(); test_readlink_and_make_absolute();
test_get_files_in_directory(); test_get_files_in_directory();
test_var_tmp(); test_var_tmp();
test_chase_symlinks(); test_chase_symlinks();
test_dot_or_dot_dot();
return 0; return 0;
} }

View File

@ -385,7 +385,7 @@ static int dir_cleanup(
usec_t age; usec_t age;
_cleanup_free_ char *sub_path = NULL; _cleanup_free_ char *sub_path = NULL;
if (STR_IN_SET(dent->d_name, ".", "..")) if (dot_or_dot_dot(dent->d_name))
continue; continue;
if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) { if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) {
@ -1070,9 +1070,7 @@ static int item_do_children(Item *i, const char *path, action_t action) {
_cleanup_free_ char *p = NULL; _cleanup_free_ char *p = NULL;
int q; int q;
errno = 0; if (dot_or_dot_dot(de->d_name))
if (STR_IN_SET(de->d_name, ".", ".."))
continue; continue;
p = strjoin(path, "/", de->d_name); p = strjoin(path, "/", de->d_name);