Introduced $ meta character in glob expressions

This commit is contained in:
valenok 2012-01-26 03:21:51 +00:00
parent 905413b656
commit 8ea40bae4b
3 changed files with 26 additions and 10 deletions

View File

@ -40,6 +40,8 @@ Matches everything
Matches everything but slash character, '/' Matches everything but slash character, '/'
.It ? .It ?
Matches any character Matches any character
.It $
Matches the end of the string
.It | .It |
Matches if pattern on the left side or the right side matches. Pattern on the Matches if pattern on the left side or the right side matches. Pattern on the
left side is matched first left side is matched first
@ -66,7 +68,7 @@ utility.
All files that fully match cgi_pattern are treated as CGI. All files that fully match cgi_pattern are treated as CGI.
Default pattern allows CGI files be Default pattern allows CGI files be
anywhere. To restrict CGIs to certain directory, use e.g. "-C /cgi-bin/**.cgi". anywhere. To restrict CGIs to certain directory, use e.g. "-C /cgi-bin/**.cgi".
Default: "**.cgi|**.pl|**.php" Default: "**.cgi$|**.pl$|**.php$"
.It Fl E Ar cgi_environment .It Fl E Ar cgi_environment
Extra environment variables to be passed to the CGI script in addition to Extra environment variables to be passed to the CGI script in addition to
standard ones. The list must be comma-separated list of X=Y pairs, like this: standard ones. The list must be comma-separated list of X=Y pairs, like this:
@ -90,7 +92,7 @@ Authorization realm. Default: "mydomain.com"
.It Fl S Ar ssi_pattern .It Fl S Ar ssi_pattern
All files that fully match ssi_pattern are treated as SSI. All files that fully match ssi_pattern are treated as SSI.
Unknown SSI directives are silently ignored. Currently, two SSI directives Unknown SSI directives are silently ignored. Currently, two SSI directives
are supported, "include" and "exec". Default: "**.shtml|**.shtm" are supported, "include" and "exec". Default: "**.shtml$|**.shtm$"
.It Fl a Ar access_log_file .It Fl a Ar access_log_file
Access log file. Default: "", no logging is done. Access log file. Default: "", no logging is done.
.It Fl d Ar enable_directory_listing .It Fl d Ar enable_directory_listing

View File

@ -410,13 +410,13 @@ enum {
}; };
static const char *config_options[] = { static const char *config_options[] = {
"C", "cgi_pattern", "**.cgi|**.pl|**.php", "C", "cgi_pattern", "**.cgi$|**.pl$|**.php$",
"E", "cgi_environment", NULL, "E", "cgi_environment", NULL,
"G", "put_delete_passwords_file", NULL, "G", "put_delete_passwords_file", NULL,
"I", "cgi_interpreter", NULL, "I", "cgi_interpreter", NULL,
"P", "protect_uri", NULL, "P", "protect_uri", NULL,
"R", "authentication_domain", "mydomain.com", "R", "authentication_domain", "mydomain.com",
"S", "ssi_pattern", "**.shtml|**.shtm", "S", "ssi_pattern", "**.shtml$|**.shtm$",
"a", "access_log_file", NULL, "a", "access_log_file", NULL,
"c", "ssl_chain_file", NULL, "c", "ssl_chain_file", NULL,
"d", "enable_directory_listing", "yes", "d", "enable_directory_listing", "yes",
@ -771,10 +771,13 @@ static int match_prefix(const char *pattern, int pattern_len, const char *str) {
match_prefix(or_str + 1, (pattern + pattern_len) - (or_str + 1), str); match_prefix(or_str + 1, (pattern + pattern_len) - (or_str + 1), str);
} }
i = j = res = 0; i = j = 0;
res = -1;
for (; i < pattern_len; i++, j++) { for (; i < pattern_len; i++, j++) {
if (pattern[i] == '?' && str[j] != '\0') { if (pattern[i] == '?' && str[j] != '\0') {
continue; continue;
} else if (pattern[i] == '$') {
return str[j] == '\0' ? j : -1;
} else if (pattern[i] == '*') { } else if (pattern[i] == '*') {
i++; i++;
if (pattern[i] == '*') { if (pattern[i] == '*') {
@ -788,10 +791,10 @@ static int match_prefix(const char *pattern, int pattern_len, const char *str) {
} }
do { do {
res = match_prefix(pattern + i, pattern_len - i, str + j + len); res = match_prefix(pattern + i, pattern_len - i, str + j + len);
} while (res == 0 && len-- > 0); } while (res == -1 && len-- > 0);
return res == 0 ? 0 : j + res + len; return res == -1 ? -1 : j + res + len;
} else if (pattern[i] != str[j]) { } else if (pattern[i] != str[j]) {
return 0; return -1;
} }
} }
return j; return j;

View File

@ -2,7 +2,7 @@
int main(void) { int main(void) {
assert(match_prefix("/a/", 3, "/a/b/c") == 3); assert(match_prefix("/a/", 3, "/a/b/c") == 3);
assert(match_prefix("/a/", 3, "/ab/c") == 0); assert(match_prefix("/a/", 3, "/ab/c") == -1);
assert(match_prefix("/*/", 3, "/ab/c") == 4); assert(match_prefix("/*/", 3, "/ab/c") == 4);
assert(match_prefix("**", 2, "/a/b/c") == 6); assert(match_prefix("**", 2, "/a/b/c") == 6);
assert(match_prefix("/*", 2, "/a/b/c") == 2); assert(match_prefix("/*", 2, "/a/b/c") == 2);
@ -12,8 +12,19 @@ int main(void) {
assert(match_prefix("a|b|cd", 6, "cdef") == 2); assert(match_prefix("a|b|cd", 6, "cdef") == 2);
assert(match_prefix("a|b|c?", 6, "cdef") == 2); assert(match_prefix("a|b|c?", 6, "cdef") == 2);
assert(match_prefix("a|?|cd", 6, "cdef") == 1); assert(match_prefix("a|?|cd", 6, "cdef") == 1);
assert(match_prefix("/a/**.cgi", 9, "/foo/bar/x.cgi") == 0); assert(match_prefix("/a/**.cgi", 9, "/foo/bar/x.cgi") == -1);
assert(match_prefix("/a/**.cgi", 9, "/a/bar/x.cgi") == 12); assert(match_prefix("/a/**.cgi", 9, "/a/bar/x.cgi") == 12);
assert(match_prefix("**/", 3, "/a/b/c") == 5);
assert(match_prefix("**/$", 4, "/a/b/c") == -1);
assert(match_prefix("**/$", 4, "/a/b/") == 5);
assert(match_prefix("$", 1, "") == 0);
assert(match_prefix("$", 1, "x") == -1);
assert(match_prefix("*$", 2, "x") == 1);
assert(match_prefix("/$", 2, "/") == 1);
assert(match_prefix("*", 1, "/hello/") == 0);
assert(match_prefix("**.a$|**.b$", 11, "/a/b.b/") == -1);
assert(match_prefix("**.a$|**.b$", 11, "/a/b.b") == 6);
assert(match_prefix("**.a$|**.b$", 11, "/a/b.a") == 6);
return 0; return 0;
} }