diff --git a/mongoose.1 b/mongoose.1 index 11524926..60129cba 100644 --- a/mongoose.1 +++ b/mongoose.1 @@ -40,6 +40,8 @@ Matches everything Matches everything but slash character, '/' .It ? Matches any character +.It $ +Matches the end of the string .It | Matches if pattern on the left side or the right side matches. Pattern on the left side is matched first @@ -66,7 +68,7 @@ utility. All files that fully match cgi_pattern are treated as CGI. Default pattern allows CGI files be 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 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: @@ -90,7 +92,7 @@ Authorization realm. Default: "mydomain.com" .It Fl S Ar ssi_pattern All files that fully match ssi_pattern are treated as SSI. 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 Access log file. Default: "", no logging is done. .It Fl d Ar enable_directory_listing diff --git a/mongoose.c b/mongoose.c index a4070ec6..fb7e7f92 100644 --- a/mongoose.c +++ b/mongoose.c @@ -410,13 +410,13 @@ enum { }; static const char *config_options[] = { - "C", "cgi_pattern", "**.cgi|**.pl|**.php", + "C", "cgi_pattern", "**.cgi$|**.pl$|**.php$", "E", "cgi_environment", NULL, "G", "put_delete_passwords_file", NULL, "I", "cgi_interpreter", NULL, "P", "protect_uri", NULL, "R", "authentication_domain", "mydomain.com", - "S", "ssi_pattern", "**.shtml|**.shtm", + "S", "ssi_pattern", "**.shtml$|**.shtm$", "a", "access_log_file", NULL, "c", "ssl_chain_file", NULL, "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); } - i = j = res = 0; + i = j = 0; + res = -1; for (; i < pattern_len; i++, j++) { if (pattern[i] == '?' && str[j] != '\0') { continue; + } else if (pattern[i] == '$') { + return str[j] == '\0' ? j : -1; } else if (pattern[i] == '*') { i++; if (pattern[i] == '*') { @@ -788,10 +791,10 @@ static int match_prefix(const char *pattern, int pattern_len, const char *str) { } do { res = match_prefix(pattern + i, pattern_len - i, str + j + len); - } while (res == 0 && len-- > 0); - return res == 0 ? 0 : j + res + len; + } while (res == -1 && len-- > 0); + return res == -1 ? -1 : j + res + len; } else if (pattern[i] != str[j]) { - return 0; + return -1; } } return j; diff --git a/test/unit_test.c b/test/unit_test.c index c68fc250..65f9778b 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -2,7 +2,7 @@ int main(void) { 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("**", 2, "/a/b/c") == 6); 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|c?", 6, "cdef") == 2); 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("**/", 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; }