mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
path-util: use path_find_first_component() in path_startswith()
This makes path_startswith() stricter. If one of the path component in arguments is longer than NAME_MAX, it returns NULL.
This commit is contained in:
parent
0b8696256b
commit
63f11e354a
@ -430,7 +430,7 @@ int path_simplify_and_warn(
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* path_startswith(const char *path, const char *prefix) {
|
||||
char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) {
|
||||
assert(path);
|
||||
assert(prefix);
|
||||
|
||||
@ -448,28 +448,25 @@ char* path_startswith(const char *path, const char *prefix) {
|
||||
return NULL;
|
||||
|
||||
for (;;) {
|
||||
size_t a, b;
|
||||
const char *p, *q;
|
||||
int r, k;
|
||||
|
||||
path += strspn(path, "/");
|
||||
prefix += strspn(prefix, "/");
|
||||
|
||||
if (*prefix == 0)
|
||||
return (char*) path;
|
||||
|
||||
if (*path == 0)
|
||||
r = path_find_first_component(&path, accept_dot_dot, &p);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
a = strcspn(path, "/");
|
||||
b = strcspn(prefix, "/");
|
||||
|
||||
if (a != b)
|
||||
k = path_find_first_component(&prefix, accept_dot_dot, &q);
|
||||
if (k < 0)
|
||||
return NULL;
|
||||
|
||||
if (memcmp(path, prefix, a) != 0)
|
||||
if (k == 0)
|
||||
return (char*) (p ?: path);
|
||||
|
||||
if (r != k)
|
||||
return NULL;
|
||||
|
||||
path += a;
|
||||
prefix += b;
|
||||
if (!strneq(p, q, r))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,10 @@ char* path_make_absolute(const char *p, const char *prefix);
|
||||
int safe_getcwd(char **ret);
|
||||
int path_make_absolute_cwd(const char *p, char **ret);
|
||||
int path_make_relative(const char *from_dir, const char *to_path, char **_r);
|
||||
char* path_startswith(const char *path, const char *prefix) _pure_;
|
||||
char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_;
|
||||
static inline char* path_startswith(const char *path, const char *prefix) {
|
||||
return path_startswith_full(path, prefix, true);
|
||||
}
|
||||
int path_compare(const char *a, const char *b) _pure_;
|
||||
bool path_equal(const char *a, const char *b) _pure_;
|
||||
bool path_equal_or_files_same(const char *a, const char *b, int flags);
|
||||
|
@ -473,49 +473,42 @@ static void test_strv_resolve(void) {
|
||||
assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
|
||||
}
|
||||
|
||||
static void test_path_startswith(void) {
|
||||
const char *p;
|
||||
static void test_path_startswith_one(const char *path, const char *prefix, const char *skipped, const char *expected) {
|
||||
const char *p, *q;
|
||||
|
||||
log_debug("/* %s(%s, %s) */", __func__, path, prefix);
|
||||
|
||||
p = path_startswith(path, prefix);
|
||||
assert_se(streq_ptr(p, expected));
|
||||
if (p) {
|
||||
q = strjoina(skipped, p);
|
||||
assert_se(streq(q, path));
|
||||
assert_se(p == path + strlen(skipped));
|
||||
}
|
||||
}
|
||||
|
||||
static void test_path_startswith(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/foo");
|
||||
assert_se(streq_ptr(p, "bar/barfoo/"));
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo", "/foo/", "bar/barfoo/");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/", "/foo/", "bar/barfoo/");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/", "/", "foo/bar/barfoo/");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "////", "/", "foo/bar/barfoo/");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo//bar/////barfoo///", "/foo/bar/barfoo/", "");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/bar/barfoo////", "/foo/bar/barfoo/", "");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/bar///barfoo/", "/foo/bar/barfoo/", "");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo////bar/barfoo/", "/foo/bar/barfoo/", "");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "////foo/bar/barfoo/", "/foo/bar/barfoo/", "");
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/bar/barfoo", "/foo/bar/barfoo/", "");
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/foo/");
|
||||
assert_se(streq_ptr(p, "bar/barfoo/"));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/");
|
||||
assert_se(streq_ptr(p, "foo/bar/barfoo/"));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "////");
|
||||
assert_se(streq_ptr(p, "foo/bar/barfoo/"));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/foo//bar/////barfoo///");
|
||||
assert_se(streq_ptr(p, ""));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo////");
|
||||
assert_se(streq_ptr(p, ""));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/foo/bar///barfoo/");
|
||||
assert_se(streq_ptr(p, ""));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/foo////bar/barfoo/");
|
||||
assert_se(streq_ptr(p, ""));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "////foo/bar/barfoo/");
|
||||
assert_se(streq_ptr(p, ""));
|
||||
|
||||
p = path_startswith("/foo/bar/barfoo/", "/foo/bar/barfoo");
|
||||
assert_se(streq_ptr(p, ""));
|
||||
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa/"));
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfooa"));
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", ""));
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", "/bar/foo"));
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", "/f/b/b/"));
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/barfo"));
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", "/foo/bar/bar"));
|
||||
assert_se(!path_startswith("/foo/bar/barfoo/", "/fo"));
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/bar/barfooa/", NULL, NULL);
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/bar/barfooa", NULL, NULL);
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "", NULL, NULL);
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/bar/foo", NULL, NULL);
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/f/b/b/", NULL, NULL);
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/bar/barfo", NULL, NULL);
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/foo/bar/bar", NULL, NULL);
|
||||
test_path_startswith_one("/foo/bar/barfoo/", "/fo", NULL, NULL);
|
||||
}
|
||||
|
||||
static void test_prefix_root_one(const char *r, const char *p, const char *expected) {
|
||||
|
Loading…
Reference in New Issue
Block a user