mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 19:01:57 -04:00
Reject unterminated wildcard character classes in filter allocation
This commit is contained in:
parent
dee434f09b
commit
527bd69129
2 changed files with 75 additions and 0 deletions
|
|
@ -31,6 +31,38 @@ void content_free(void* void_content)
|
|||
free(content);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that all wildcard character classes are terminated.
|
||||
*
|
||||
* Escaped '[' characters are literals and don't start a class.
|
||||
* Escape characters inside a class are literals, consistently with
|
||||
* match_class().
|
||||
*/
|
||||
static int filter_pattern_class_valid(const char* pattern)
|
||||
{
|
||||
const char* i;
|
||||
int in_class = 0;
|
||||
|
||||
for (i = pattern; *i; ++i) {
|
||||
if (in_class) {
|
||||
if (*i == ']')
|
||||
in_class = 0;
|
||||
} else {
|
||||
#ifdef _WIN32
|
||||
if (*i == '^' && i[1] != 0) {
|
||||
#else
|
||||
if (*i == '\\' && i[1] != 0) {
|
||||
#endif
|
||||
++i;
|
||||
} else if (*i == '[') {
|
||||
in_class = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return !in_class;
|
||||
}
|
||||
|
||||
struct snapraid_filter* filter_alloc_file(int direction, const char* root, const char* pattern)
|
||||
{
|
||||
struct snapraid_filter* filter;
|
||||
|
|
@ -46,6 +78,12 @@ struct snapraid_filter* filter_alloc_file(int direction, const char* root, const
|
|||
pathimport(filter->root, sizeof(filter->root), root);
|
||||
filter->direction = direction;
|
||||
|
||||
/* reject unterminated wildcard character classes */
|
||||
if (!filter_pattern_class_valid(filter->pattern)) {
|
||||
free(filter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reject the root directory and standalone absolute directory wildcard as invalid patterns */
|
||||
if (pathcmp(filter->pattern, "/") == 0 || pathcmp(filter->pattern, "/**/") == 0) {
|
||||
free(filter);
|
||||
|
|
@ -128,6 +166,12 @@ struct snapraid_filter* filter_alloc_disk(int direction, const char* pattern)
|
|||
pathimport(filter->pattern, sizeof(filter->pattern), pattern);
|
||||
filter->direction = direction;
|
||||
|
||||
/* reject unterminated wildcard character classes */
|
||||
if (!filter_pattern_class_valid(filter->pattern)) {
|
||||
free(filter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* it's a disk filter */
|
||||
filter->is_disk = 1;
|
||||
filter->is_abs = 0;
|
||||
|
|
|
|||
|
|
@ -1031,6 +1031,34 @@ struct {
|
|||
{ "foo/.hidden", 1 },
|
||||
{ "foo/..hidden", 1 },
|
||||
|
||||
/* invalid unterminated character classes */
|
||||
{ "[", 0 },
|
||||
{ "foo[", 0 },
|
||||
{ "[abc", 0 },
|
||||
{ "foo/[ab", 0 },
|
||||
{ "/foo/[ab/bar", 0 },
|
||||
{ "foo/[a-z", 0 },
|
||||
|
||||
/* valid character classes */
|
||||
{ "[abc]", 1 },
|
||||
{ "foo[abc]", 1 },
|
||||
{ "foo/[ab]/bar", 1 },
|
||||
{ "foo/[a-z]/bar", 1 },
|
||||
|
||||
#ifdef _WIN32
|
||||
/* escaped '[' is literal */
|
||||
{ "foo^[bar", 1 },
|
||||
|
||||
/* escaped '^' followed by '[' starts a class */
|
||||
{ "foo^^[bar", 0 },
|
||||
#else
|
||||
/* escaped '[' is literal */
|
||||
{ "foo\\[bar", 1 },
|
||||
|
||||
/* escaped '\' followed by '[' starts a class */
|
||||
{ "foo\\\\[bar", 0 },
|
||||
#endif
|
||||
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
|
@ -1043,6 +1071,9 @@ static const struct {
|
|||
{ "disk", 1 },
|
||||
{ "disk?", 1 },
|
||||
{ "data*", 1 },
|
||||
{ "[ab", 0 },
|
||||
{ "disk[12", 0 },
|
||||
{ "disk[12]", 1 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue