浏览代码

Introduced $ meta character in glob expressions

valenok 13 年之前
父节点
当前提交
8ea40bae4b
共有 3 个文件被更改,包括 26 次插入10 次删除
  1. 4 2
      mongoose.1
  2. 9 6
      mongoose.c
  3. 13 2
      test/unit_test.c

+ 4 - 2
mongoose.1

@@ -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

+ 9 - 6
mongoose.c

@@ -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);
-      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]) {
     } else if (pattern[i] != str[j]) {
-      return 0;
+      return -1;
     }
     }
   }
   }
   return j;
   return j;

+ 13 - 2
test/unit_test.c

@@ -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;
 }
 }