gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [gnurl] 39/150: fnmatch: accept an alphanum to be followed


From: gnunet
Subject: [GNUnet-SVN] [gnurl] 39/150: fnmatch: accept an alphanum to be followed by a non-alphanum in char set
Date: Fri, 30 Mar 2018 16:48:13 +0200

This is an automated email from the git hooks/post-receive script.

ng0 pushed a commit to branch master
in repository gnurl.

commit fcaa1826bd34c2a7ea7e71bfd2cfdcf5fe3506c1
Author: Patrick Monnerat <address@hidden>
AuthorDate: Mon Jan 29 16:21:50 2018 +0100

    fnmatch: accept an alphanum to be followed by a non-alphanum in char set
    
    Also be more tolerant about set pattern syntax.
    Update unit test 1307 accordingly.
    
    Bug: https://curl.haxx.se/mail/lib-2018-01/0114.html
---
 lib/curl_fnmatch.c    | 143 +++++++++++++++++++-------------------------------
 tests/unit/unit1307.c |  11 ++--
 2 files changed, 61 insertions(+), 93 deletions(-)

diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index 5b6d28c06..bb50a2684 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -53,8 +53,6 @@ typedef enum {
 
 typedef enum {
   CURLFNM_SCHS_DEFAULT = 0,
-  CURLFNM_SCHS_MAYRANGE,
-  CURLFNM_SCHS_MAYRANGE2,
   CURLFNM_SCHS_RIGHTBR,
   CURLFNM_SCHS_RIGHTBRLEFTBR
 } setcharset_state;
@@ -64,6 +62,13 @@ typedef enum {
   CURLFNM_PKW_DDOT
 } parsekey_state;
 
+typedef enum {
+  CCLASS_OTHER = 0,
+  CCLASS_DIGIT,
+  CCLASS_UPPER,
+  CCLASS_LOWER
+} char_class;
+
 #define SETCHARSET_OK     1
 #define SETCHARSET_FAIL   0
 
@@ -123,14 +128,48 @@ static int parsekeyword(unsigned char **pattern, unsigned 
char *charset)
   return SETCHARSET_OK;
 }
 
+/* Return the character class. */
+static char_class charclass(unsigned char c)
+{
+  if(ISUPPER(c))
+    return CCLASS_UPPER;
+  if(ISLOWER(c))
+    return CCLASS_LOWER;
+  if(ISDIGIT(c))
+    return CCLASS_DIGIT;
+  return CCLASS_OTHER;
+}
+
+/* Include a character or a range in set. */
+static void setcharorrange(unsigned char **pp, unsigned char *charset)
+{
+  unsigned char *p = (*pp)++;
+  unsigned char c = *p++;
+
+  charset[c] = 1;
+  if(ISALNUM(c) && *p++ == '-') {
+    char_class cc = charclass(c);
+    unsigned char endrange = *p++;
+
+    if(endrange == '\\')
+      endrange = *p++;
+    if(endrange >= c && charclass(endrange) == cc) {
+      while(c++ != endrange)
+        if(charclass(c) == cc)  /* Chars in class may be not consecutive. */
+          charset[c] = 1;
+      *pp = p;
+    }
+  }
+}
+
 /* returns 1 (true) if pattern is OK, 0 if is bad ("p" is pattern pointer) */
 static int setcharset(unsigned char **p, unsigned char *charset)
 {
   setcharset_state state = CURLFNM_SCHS_DEFAULT;
-  unsigned char rangestart = 0;
-  unsigned char lastchar   = 0;
   bool something_found = FALSE;
   unsigned char c;
+
+  memset(charset, 0, CURLFNM_CHSET_SIZE);
   for(;;) {
     c = **p;
     if(!c)
@@ -138,14 +177,7 @@ static int setcharset(unsigned char **p, unsigned char 
*charset)
 
     switch(state) {
     case CURLFNM_SCHS_DEFAULT:
-      if(ISALNUM(c)) { /* ASCII value */
-        rangestart = c;
-        charset[c] = 1;
-        (*p)++;
-        state = CURLFNM_SCHS_MAYRANGE;
-        something_found = TRUE;
-      }
-      else if(c == ']') {
+      if(c == ']') {
         if(something_found)
           return SETCHARSET_OK;
         something_found = TRUE;
@@ -169,11 +201,6 @@ static int setcharset(unsigned char **p, unsigned char 
*charset)
         }
         something_found = TRUE;
       }
-      else if(c == '?' || c == '*') {
-        something_found = TRUE;
-        charset[c] = 1;
-        (*p)++;
-      }
       else if(c == '^' || c == '!') {
         if(!something_found) {
           if(charset[CURLFNM_NEGATE]) {
@@ -189,82 +216,17 @@ static int setcharset(unsigned char **p, unsigned char 
*charset)
       }
       else if(c == '\\') {
         c = *(++(*p));
-        if(ISPRINT((c))) {
-          something_found = TRUE;
-          state = CURLFNM_SCHS_MAYRANGE;
-          charset[c] = 1;
-          rangestart = c;
-          (*p)++;
-        }
+        if(c)
+          setcharorrange(p, charset);
         else
-          return SETCHARSET_FAIL;
+          charset['\\'] = 1;
+        something_found = TRUE;
       }
       else {
-        charset[c] = 1;
-        (*p)++;
+        setcharorrange(p, charset);
         something_found = TRUE;
       }
       break;
-    case CURLFNM_SCHS_MAYRANGE:
-      if(c == '-') {
-        charset[c] = 1;
-        (*p)++;
-        lastchar = '-';
-        state = CURLFNM_SCHS_MAYRANGE2;
-      }
-      else if(c == '[') {
-        state = CURLFNM_SCHS_DEFAULT;
-      }
-      else if(ISALNUM(c)) {
-        charset[c] = 1;
-        (*p)++;
-      }
-      else if(c == '\\') {
-        c = *(++(*p));
-        if(ISPRINT(c)) {
-          charset[c] = 1;
-          (*p)++;
-        }
-        else
-          return SETCHARSET_FAIL;
-      }
-      else if(c == ']') {
-        return SETCHARSET_OK;
-      }
-      else
-        return SETCHARSET_FAIL;
-      break;
-    case CURLFNM_SCHS_MAYRANGE2:
-      if(c == ']') {
-        return SETCHARSET_OK;
-      }
-      else if(c == '\\') {
-        c = *(++(*p));
-        if(ISPRINT(c)) {
-          charset[c] = 1;
-          state = CURLFNM_SCHS_DEFAULT;
-          (*p)++;
-        }
-        else
-          return SETCHARSET_FAIL;
-      }
-      else if(c >= rangestart) {
-        if((ISLOWER(c) && ISLOWER(rangestart)) ||
-           (ISDIGIT(c) && ISDIGIT(rangestart)) ||
-           (ISUPPER(c) && ISUPPER(rangestart))) {
-          charset[lastchar] = 0;
-          rangestart++;
-          while(rangestart++ <= c)
-            charset[rangestart-1] = 1;
-          (*p)++;
-          state = CURLFNM_SCHS_DEFAULT;
-        }
-        else
-          return SETCHARSET_FAIL;
-      }
-      else
-        return SETCHARSET_FAIL;
-      break;
     case CURLFNM_SCHS_RIGHTBR:
       if(c == '[') {
         state = CURLFNM_SCHS_RIGHTBRLEFTBR;
@@ -383,13 +345,14 @@ static int loop(const unsigned char *pattern, const 
unsigned char *string,
           if(found) {
             p = pp + 1;
             s++;
-            memset(charset, 0, CURLFNM_CHSET_SIZE);
           }
           else
             return CURL_FNMATCH_NOMATCH;
         }
-        else
-          return CURL_FNMATCH_FAIL;
+        else {
+          if(*p++ != *s++)
+            return CURL_FNMATCH_NOMATCH;
+        }
       }
       else {
         if(*p++ != *s++)
diff --git a/tests/unit/unit1307.c b/tests/unit/unit1307.c
index eff5edebc..5aa23d0dc 100644
--- a/tests/unit/unit1307.c
+++ b/tests/unit/unit1307.c
@@ -36,8 +36,8 @@ struct testcase {
 static const struct testcase tests[] = {
   /* brackets syntax */
   { "\\[",                      "[",                      MATCH },
-  { "[",                        "[",                      RE_ERR },
-  { "[]",                       "[]",                     RE_ERR },
+  { "[",                        "[",                      MATCH },
+  { "[]",                       "[]",                     MATCH },
   { "[][]",                     "[",                      MATCH },
   { "[][]",                     "]",                      MATCH },
   { "[[]",                      "[",                      MATCH },
@@ -49,6 +49,8 @@ static const struct testcase tests[] = {
   { "[][[[]",                   "[",                      MATCH },
   { "[[]",                      "]",                      NOMATCH },
 
+  { "address@hidden",                     "a",                      MATCH },
+
   { "[a-z]",                    "a",                      MATCH },
   { "[a-z]",                    "A",                      NOMATCH },
   { "?[a-z]",                   "?Z",                     NOMATCH },
@@ -77,6 +79,7 @@ static const struct testcase tests[] = {
   { "[][?*-]",                  "*",                      MATCH },
   { "[][?*-]",                  "-",                      MATCH },
   { "[]?*-]",                   "-",                      MATCH },
+  { "[\xFF]",                   "\xFF",                   MATCH },
   { "?/b/c",                    "a/b/c",                  MATCH },
   { "^_{}~",                    "^_{}~",                  MATCH },
   { "!#%+,-./01234567889",      "!#%+,-./01234567889",    MATCH },
@@ -98,7 +101,9 @@ static const struct testcase tests[] = {
   { "*[^a].t?t",                "ba.txt",                 NOMATCH },
   { "*[^a].t?t",                "ab.txt",                 MATCH },
   { "*[^a]",                    "",                       NOMATCH },
-  { "[!ΓΏ]",                     "",                       NOMATCH },
+  { "[!\xFF]",                  "",                       NOMATCH },
+  { "[!\xFF]",                  "\xFF",                   NOMATCH },
+  { "[!\xFF]",                  "a",                      MATCH },
   { "[!?*[]",                   "?",                      NOMATCH },
   { "[!!]",                     "!",                      NOMATCH },
   { "[!!]",                     "x",                      MATCH },

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]