Make match_ircglob() work more like the ircd.
authorMichael Poole <mdpoole@troilus.org>
Mon, 30 May 2005 15:14:56 +0000 (15:14 +0000)
committerMichael Poole <mdpoole@troilus.org>
Mon, 30 May 2005 15:14:56 +0000 (15:14 +0000)
src/tools.c (match_ircglob): Limit glob backtracking in the same way
that ircds generally do.
git-archimport-id: srvx@srvx.net--2005-srvx/srvx--devo--1.3--patch-21

ChangeLog
src/tools.c

index 6b32bfd5b2eacd925b036578cbae14977eb1af4e..a11f7191f6ae4548bf1256d7ca986f896bcc6f4f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,20 @@
 # arch-tag: automatic-ChangeLog--srvx@srvx.net--2005-srvx/srvx--devo--1.3
 #
 
+2005-05-30 15:14:56 GMT        Michael Poole <mdpoole@troilus.org>     patch-21
+
+    Summary:
+      Make match_ircglob() work more like the ircd.
+    Revision:
+      srvx--devo--1.3--patch-21
+
+    src/tools.c (match_ircglob): Limit glob backtracking in the same way
+    that ircds generally do.
+
+    modified files:
+     ChangeLog src/tools.c
+
+
 2005-05-01 17:16:58 GMT        Michael Poole <mdpoole@troilus.org>     patch-20
 
     Summary:
index 973bc53bb823455cc1fce85313c2e690a641336a..934c04372297ae56233e673ac4ac055bacd522dc 100644 (file)
@@ -245,63 +245,57 @@ int mmatch(const char *old_mask, const char *new_mask)
 int
 match_ircglob(const char *text, const char *glob)
 {
-    unsigned int star_p, q_cnt;
-    while (1) {
-       switch (*glob) {
-       case 0:
-           return !*text;
-        case '\\':
-            glob++;
-            /* intentionally not tolower(...) so people can force
-             * capitalization, or we can overload \ in the future */
-            if (*text++ != *glob++)
-                return 0;
-            break;
-       case '*':
-        case '?':
-            star_p = q_cnt = 0;
-            do {
-                if (*glob == '*')
-                    star_p = 1;
-                else if (*glob == '?')
-                    q_cnt++;
-                else
-                    break;
-                glob++;
-            } while (1);
-            while (q_cnt) {
-                if (!*text++)
-                    return 0;
-                q_cnt--;
-            }
-            if (star_p) {
-                /* if this is the last glob character, it will match any text */
-                if (!*glob)
-                    return 1;
-                /* Thanks to the loop above, we know that the next
-                 * character is a normal character.  So just look for
-                 * the right character.
-                 */
-                for (; *text; text++) {
-                    if ((tolower(*text) == tolower(*glob))
-                        && match_ircglob(text+1, glob+1)) {
-                        return 1;
-                    }
-                }
-                return 0;
-            }
-            /* if !star_p, fall through to normal character case,
-             * first checking to see if ?s carried us to the end */
-            if (!*glob && !*text)
+    const char *m = glob, *n = text;
+    const char *m_tmp = glob, *n_tmp = text;
+    int star_p;
+
+    for (;;) switch (*m) {
+    case '\0':
+        if (!*n)
+            return 1;
+    backtrack:
+        if (m_tmp == glob)
+            return 0;
+        m = m_tmp;
+        n = ++n_tmp;
+        break;
+    case '\\':
+        m++;
+        /* allow escaping to force capitalization */
+        if (*m++ != *n++)
+            return 0;
+        break;
+    case '*': case '?':
+        for (star_p = 0; ; m++) {
+            if (*m == '*')
+                star_p = 1;
+            else if (*m == '?') {
+                if (!*n++)
+                    goto backtrack;
+            } else break;
+        }
+        if (star_p) {
+            if (!*m)
                 return 1;
-       default:
-           if (!*text)
-                return 0;
-           while (*text && *glob && *glob != '*' && *glob != '?' && *glob != '\\') {
-               if (tolower(*text++) != tolower(*glob++))
+            else if (*m == '\\') {
+                m_tmp = ++m;
+                if (!*m)
                     return 0;
-           }
-       }
+                for (n_tmp = n; *n && *n != *m; n++) ;
+            } else {
+                m_tmp = m;
+                for (n_tmp = n; *n && tolower(*n) != tolower(*m); n++) ;
+            }
+        }
+        /* and fall through */
+    default:
+        if (!*n)
+            return *m != '\0';
+        if (tolower(*m) != tolower(*n))
+            goto backtrack;
+        m++;
+        n++;
+        break;
     }
 }