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! |
sievebug.patch
Description: sievebug.patch