Reject standalone absolute directory filter pattern /**/ during parsing

This commit is contained in:
Andrea Mazzoleni 2026-08-26 13:02:55 +02:00
parent 9e5f51fa5b
commit d4dc5a7339
5 changed files with 46 additions and 2 deletions

View file

@ -45,8 +45,8 @@ struct snapraid_filter* filter_alloc_file(int direction, const char* root, const
pathimport(filter->root, sizeof(filter->root), root);
filter->direction = direction;
/* reject the root directory as an invalid pattern */
if (pathcmp(filter->pattern, "/") == 0) {
/* reject the root directory and standalone absolute directory wildcard as invalid patterns */
if (pathcmp(filter->pattern, "/") == 0 || pathcmp(filter->pattern, "/**/") == 0) {
free(filter);
return 0;
}

View file

@ -896,6 +896,44 @@ static void test_wnmatch(void)
}
}
struct {
const char* pattern;
int valid;
} FILTER_TEST[] = {
/* invalid standalone root and standalone double-star patterns */
{ "/", 0 },
{ "/**/", 0 },
/* valid single and multi-level patterns */
{ "/foo/", 1 },
{ "/foo/**/", 1 },
{ "/**/foo/", 1 },
{ "/foo/**/bar", 1 },
{ "/foo/**/bar/", 1 },
{ "foo/**/bar", 1 },
{ "foo/**/", 1 },
{ "**", 1 },
{ "**/", 1 },
{ 0, 0 }
};
static void test_filter(void)
{
for (int i = 0; FILTER_TEST[i].pattern; ++i) {
struct snapraid_filter* f = filter_alloc_file(1, "", FILTER_TEST[i].pattern);
if ((f != 0) != FILTER_TEST[i].valid) {
/* LCOV_EXCL_START */
log_fatal(EINTERNAL, "Failed filter test '%s', expected %s\n",
FILTER_TEST[i].pattern, FILTER_TEST[i].valid ? "valid" : "invalid");
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (f != 0)
filter_free(f);
}
}
static void test_parse_smartctl(void)
{
char smartctl[SMART_MAX];
@ -1169,6 +1207,9 @@ void selftest(void)
/* wildcard and path pattern matching */
test_wnmatch();
/* filter pattern parsing */
test_filter();
/* smartctl output parsing */
test_parse_smartctl();

View file

@ -1988,6 +1988,7 @@ at any depth in a directory tree without knowing the exact path structure.
For example, the pattern \`src/**/main.js\` matches \`src/main.js\` (skipping
zero directories), \`src/ui/main.js\` (skipping one directory), and
\`src/ui/components/main.js\` (skipping two directories).
The standalone form \`/**/\` is not accepted as a complete pattern.
.PP
Character classes using square brackets match a single character from a
specified set or range. Like the other single character patterns, they do

View file

@ -1593,6 +1593,7 @@ Pattern
For example, the pattern `src/**/main.js` matches `src/main.js` (skipping
zero directories), `src/ui/main.js` (skipping one directory), and
`src/ui/components/main.js` (skipping two directories).
The standalone form `/**/` is not accepted as a complete pattern.
Character classes using square brackets match a single character from a
specified set or range. Like the other single character patterns, they do

View file

@ -1706,6 +1706,7 @@ at any depth in a directory tree without knowing the exact path structure.
For example, the pattern `src/**/main.js` matches `src/main.js` (skipping
zero directories), `src/ui/main.js` (skipping one directory), and
`src/ui/components/main.js` (skipping two directories).
The standalone form `/**/` is not accepted as a complete pattern.
Character classes using square brackets match a single character from a
specified set or range. Like the other single character patterns, they do