Hy!

 (Hope you're not seeing this mail twice.)


 I might have hit a bug.

 I tried a SIEVE script on a test mail that had a 
 subject: "[Prim]xx" (without quotes, of course)

 The script's condition section:
 --------------------------------------------
 if header :matches "Subject" "[Prim]*"
 --------------------------------------------
 By common sense, this should match. But it doesn't.

 What does match:
 --------------------------------------------
 if header :matches "Subject" "\\[Prim]*"
 --------------------------------------------

 And the cause?

 Cyrus uses the unix fnmatch() function, which was made for matching filenames.
And that is the reason it has one "side-effect": it interprets not only * and ?
characters, but also [ ] chars.
 And from "our" point of view, that's bad.

 I've read the RFC, and it doesn't specify that you have to escape the [ char
(and this is only logical).

 I've attached a fix, it should be good (also included below).

 There may be problems with the "*" characters escaped to "\\*" (that should
instead be "\*", which is in a C source file "\\*"). The RFC is not really clear
about this!


*** comparator.c.original       Fri Jan  4 00:49:34 2002
--- comparator.c        Fri Jan  4 02:04:59 2002
***************
*** 38,43 ****
--- 38,70 ----
  #include "tree.h"
  #include "sieve.h"
  
+ /* string_match added by Noll Janos <[EMAIL PROTECTED]> */
+ static int string_match(const char *pat, const char *text)
+ {
+     int ret,nt;
+     char *epat; /* will be the pattern, [-escaped */
+     char *p,*q;
+ 
+     if (!strchr(pat,'[')) { /* no [ - no problem */
+         ret = !fnmatch(pat, text, 0);
+     } else {
+       /* count how many ['s there are */
+         for ( nt=-1, p=(char *)pat-1 ; p!=NULL ; p=strchr(p+1,'[') ) nt++;
+ 
+       /* copy and escape ['s */
+       epat=(char *)malloc(strlen(pat)+nt+1);  
+       for ( p=(char *)pat,q=epat ; *p ; p++ ) {
+           if (*p=='[') { *(q++)='\\'; }
+           *(q++)=*p;
+       }
+       *q=0;
+ 
+         ret = !fnmatch(epat, text, 0);        
+       free(epat);
+     }
+     return(ret);
+ }
+ 
  /* --- i;octet comparators --- */
  
  /* just compare the two; these should be NULL terminated */
***************
*** 93,99 ****
  
  static int octet_matches(const char *pat, const char *text)
  {
!     return !fnmatch(pat, text, 0);
  }
  
  #ifdef ENABLE_REGEX
--- 120,126 ----
  
  static int octet_matches(const char *pat, const char *text)
  {
!     return string_match(pat, text);
  }
  
  #ifdef ENABLE_REGEX
***************
*** 146,152 ****
      for (i = 0; t[i] != '\0'; i++)
        t[i] = toupper(t[i]);
  
!     ret = !fnmatch(p, t, 0);
      free(p); free(t);
  
      return ret;
--- 173,179 ----
      for (i = 0; t[i] != '\0'; i++)
        t[i] = toupper(t[i]);
  
!     ret = string_match(p, t);
      free(p); free(t);
  
      return ret;

-----------------------------------------------------------------


| Noll Janos <[EMAIL PROTECTED]> | http://www.johnzero.hu |
| "Expect the unexpected!"    | ICQ# 4547866 |  Linux rulez! |

Attachment: sievebug.patch
Description: sievebug.patch

Reply via email to