Committer  : entrope
CVSROOT    : /cvsroot/undernet-ircu
Module     : ircu2.10
Commit time: 2005-05-30 15:11:50 UTC

Modified files:
     ChangeLog ircd/match.c ircd/test/Makefile.in
     ircd/test/test_stub.c

Added files:
     ircd/test/ircd_match_t.c

Log message:

Correctly match globs that end in escaped wildcards.

---------------------- diff included ----------------------
Index: ircu2.10/ChangeLog
diff -u ircu2.10/ChangeLog:1.636 ircu2.10/ChangeLog:1.637
--- ircu2.10/ChangeLog:1.636    Mon May 30 06:23:24 2005
+++ ircu2.10/ChangeLog  Mon May 30 08:11:37 2005
@@ -1,4 +1,16 @@
-2005-05-25 Reed Loden <[EMAIL PROTECTED]>
+2005-05-30  Michael Poole <[EMAIL PROTECTED]>
+
+       * ircd/match.c (match): Rewrite to handle globs that end in an
+       escaped wildcard (and hopefully clarify the code).
+
+       * ircd/test/Makefile.in: Add new ircd_match_t test program.
+
+       * ircd/test/ircd_match_t.c: New file.
+
+       * ircd/test/test_stub.c: Emite newlines after log and debug
+       messages.
+
+2005-05-25  Reed Loden <[EMAIL PROTECTED]>
 
        * ircd/s_err.c (replyTable): Allow for the specification of 'O' or
        'o' in RPL_STATSOLINE.
Index: ircu2.10/ircd/match.c
diff -u ircu2.10/ircd/match.c:1.17 ircu2.10/ircd/match.c:1.18
--- ircu2.10/ircd/match.c:1.17  Tue Apr 19 17:59:24 2005
+++ ircu2.10/ircd/match.c       Mon May 30 08:11:38 2005
@@ -18,7 +18,7 @@
  */
 /** @file
  * @brief Functions to match strings against IRC mask strings.
- * @version $Id: match.c,v 1.17 2005/04/20 00:59:24 entrope Exp $
+ * @version $Id: match.c,v 1.18 2005/05/30 15:11:38 entrope Exp $
  */
 #include "config.h"
 
@@ -190,59 +190,56 @@
 {
   const char *m = mask, *n = name;
   const char *m_tmp = mask, *n_tmp = name;
-  int wild = 0;
-
-  for (;;)
-  {
-    if (*m == '*') {
-      while (*m == '*')  /* clean up any additional wildcards */
-        m++;
-
-      m_tmp = m;
-      n_tmp = n;
-      wild = 1;
-    }
-    if (*m == '\\')  /* next wildcard is disregarded */
-      m++;
-
-    if (!*m) {
-      if (!*n)
-        return 0;  /* match */
-
-      for (m--; (m > mask) && (*m == '?'); m--);
-        ;
-
-      if (*m == '*' && (m > mask))
-        return 0;  /* match */
-
-      if (!wild)
-        return 1;
-
-      m = m_tmp;
-      n = ++n_tmp;
-    }
-    else if (!*n) {
-      while (*m == '*')  /* clean up any additional wildcards */
-        m++;
+  int star_p;
 
-      return (*m != 0);
-    }
-    if (ToLower(*m) != ToLower(*n) && *m != '?') {
-      if (!wild)
-        return 1;  /* failure! */
-
-      m = m_tmp;
-      n = ++n_tmp;
+  for (;;) switch (*m) {
+  case '\0':
+    if (!*n)
+      return 0;
+  backtrack:
+    if (m_tmp == mask)
+      return 1;
+    m = m_tmp;
+    n = ++n_tmp;
+    break;
+  case '\\':
+    m++;
+    /* allow escaping to force capitalization */
+    if (*m++ != *n++)
+      return 1;
+    break;
+  case '*': case '?':
+    for (star_p = 0; ; m++) {
+      if (*m == '*')
+        star_p = 1;
+      else if (*m == '?') {
+        if (!*n++)
+          goto backtrack;
+      } else break;
     }
-    else {
-      if (*m)
-        m++;
-      if (*n)
-        n++;
+    if (star_p) {
+      if (!*m)
+        return 0;
+      else if (*m == '\\') {
+        m_tmp = ++m;
+        if (!*m)
+          return 1;
+        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;
   }
-
-  return 1;  /* no match! */
 }
 
 /*
Index: ircu2.10/ircd/test/Makefile.in
diff -u ircu2.10/ircd/test/Makefile.in:1.3 ircu2.10/ircd/test/Makefile.in:1.4
--- ircu2.10/ircd/test/Makefile.in:1.3  Sun Jan 23 06:28:55 2005
+++ ircu2.10/ircd/test/Makefile.in      Mon May 30 08:11:39 2005
@@ -7,12 +7,14 @@
 
 TESTPROGS = \
        ircd_chattr_t \
-       ircd_string_t \
-       ircd_in_addr_t
+       ircd_in_addr_t \
+       ircd_match_t \
+       ircd_string_t
 
 DEP_SRC = \
        ircd_chattr_t.c \
        ircd_in_addr_t.c \
+       ircd_match_t.c \
        ircd_string_t.c \
        test_stub.c
 
@@ -36,14 +38,18 @@
 ircd_chattr_t: $(IRCD_CHATTR_T_OBJS)
        ${CC} -o $@ $(IRCD_CHATTR_T_OBJS)
 
-IRCD_STRING_T_OBJS = ircd_string_t.o test_stub.o ../ircd_string.o
-ircd_string_t: $(IRCD_STRING_T_OBJS)
-       ${CC} -o $@ $(IRCD_STRING_T_OBJS)
-
 IRCD_IN_ADDR_T_OBJS = ircd_in_addr_t.o test_stub.o ../ircd_alloc.o 
../ircd_string.o ../match.o ../numnicks.o
 ircd_in_addr_t: $(IRCD_IN_ADDR_T_OBJS)
        ${CC} -o $@ $(IRCD_IN_ADDR_T_OBJS)
 
+IRCD_MATCH_T_OBJS = ircd_match_t.o test_stub.o ../ircd_string.o ../match.o
+ircd_match_t: $(IRCD_MATCH_T_OBJS)
+       ${CC} -o $@ $(IRCD_MATCH_T_OBJS)
+
+IRCD_STRING_T_OBJS = ircd_string_t.o test_stub.o ../ircd_string.o
+ircd_string_t: $(IRCD_STRING_T_OBJS)
+       ${CC} -o $@ $(IRCD_STRING_T_OBJS)
+
 .c.o:
        ${CC} ${CFLAGS} ${CPPFLAGS} -c $< -o $@
 
Index: ircu2.10/ircd/test/ircd_match_t.c
diff -u /dev/null ircu2.10/ircd/test/ircd_match_t.c:1.1
--- /dev/null   Mon May 30 08:11:50 2005
+++ ircu2.10/ircd/test/ircd_match_t.c   Mon May 30 08:11:39 2005
@@ -0,0 +1,74 @@
+/*
+ * ircd_match_t.c - test cases for irc glob matching
+ */
+
+#include "ircd_log.h"
+#include "match.h"
+#include <stdio.h>
+#include <string.h>
+
+struct match_test {
+  const char *glob;
+  const char *should_match;
+  const char *shouldnt_match;
+};
+
+const struct match_test match_tests[] = {
+  { "\\*",
+    "*\0",
+    "a\0*PeacefuL*\0" },
+  { "*a*",
+    "a\0pizza\0abe\0brack\0",
+    "b\0" },
+  { "?",
+    "*\0a\0?\0",
+    "*PeacefuL*\0pizza\0???\0" },
+  { "abc",
+    "abc\0",
+    "abcd\0cabc\0" },
+  { "*abc",
+    "abc\0fooabc\0",
+    "abra\0abcd\0" },
+  { "\\?",
+    "?\0",
+    "a\0" },
+  { NULL, NULL, NULL }
+};
+
+void do_match_test(const struct match_test *test)
+{
+  const char *candidate;
+  unsigned int matched, not_matched;
+  int res;
+
+  for (candidate = test->should_match, matched = 0;
+       *candidate;
+       candidate += strlen(candidate) + 1, ++matched) {
+    res = match(test->glob, candidate);
+    if (res != 0) {
+      fprintf(stderr, "\"%s\" failed to match \"%s\".\n", test->glob, 
candidate);
+      assert(0);
+    }
+  }
+
+  for (candidate = test->shouldnt_match, not_matched = 0;
+       *candidate;
+       candidate += strlen(candidate) + 1, ++not_matched) {
+    res = match(test->glob, candidate);
+    if (res == 0) {
+      fprintf(stderr, "\"%s\" incorrectly matched \"%s\".\n", test->glob, 
candidate);
+      assert(0);
+    }
+  }
+
+  printf("Passed: %s (%u matches, %u non-matches)\n",
+         test->glob, matched, not_matched);
+}
+
+int main(int argc, char *argv[])
+{
+  const struct match_test *match;
+  for (match = match_tests; match->glob; ++match)
+    do_match_test(match);
+  return 0;
+}
Index: ircu2.10/ircd/test/test_stub.c
diff -u ircu2.10/ircd/test/test_stub.c:1.2 ircu2.10/ircd/test/test_stub.c:1.3
--- ircu2.10/ircd/test/test_stub.c:1.2  Sun Mar 20 08:06:30 2005
+++ ircu2.10/ircd/test/test_stub.c      Mon May 30 08:11:39 2005
@@ -17,6 +17,7 @@
 
     va_start(args, fmt);
     vfprintf(stderr, fmt, args);
+    fputc('\n', stderr);
     va_end(args);
 }
 
@@ -27,6 +28,7 @@
 
     va_start(args, form);
     vfprintf(stdout, form, args);
+    fputc('\n', stdout);
     va_end(args);
 }
 
----------------------- End of diff -----------------------
_______________________________________________
Patches mailing list
[email protected]
http://undernet.sbg.org/mailman/listinfo/patches

Reply via email to