[Dovecot] sieve problem email silently discard

Stephan Bosch stephan at rename-it.nl
Mon Jul 4 16:01:55 EEST 2011


Op 4-7-2011 14:19, ml at smtp.fakessh.eu schreef:
>  Le lundi 4 juillet 2011 00:40, ml at smtp.fakessh.eu a écrit :
> > I just change my sieve script by removing the implicit discard a
> > fileinto :create "Junk.spam.spam"
[...]
>  it just happened a mail that was issued in INBOX.spam.spam supposedly
>  a hit with spam than 500 which does not appear in the body of the
>  mail here
[...]
>  I do not see why this email was issued in this box

I've executed sieve-test with your script and message, which reproduces 
the problem at my end:

===
$ sieve-test -t - -T level=matching ~/fakessh.sieve ~/fakessh.eml
       ## Started executing script 'frop'
    2: header test
    2:   starting `:value-ge' match with `i;ascii-numeric' comparator:
    2:   extracting `X-Spam-score' headers from message
    2:   matching value `-1.9'
    2:     with key `500' => 1
    2:   finishing match with result: matched
    3: jump if result is false
    3:   not jumping
    5: discard action; cancel implicit keep
    6: stop command; end all script execution
       ## Finished executing script 'frop'

Performed actions:

  * discard

Implicit keep:

   (none)

sieve-test(stephan): Info: final result: success
===

This turns out to be a classic mistake actually (which I didn't think of 
either). It is related to the (admittedly counter-intuitive) nature of 
the i;ascii-numeric comparator.

 From RFC4790, Section 9.1.1 
(http://tools.ietf.org/html/rfc4790#section-9.1.1):
`The "i;ascii-numeric" collation is a simple collation intended for use 
with arbitrarily-sized, unsigned decimal integer numbers stored as octet 
strings. US-ASCII digits (0x30 to 0x39) represent digits of the numbers. 
Before converting from string to integer, the input string is truncated 
at the first non-digit character. All input is valid; strings that do 
not start with a digit represent positive infinity.'

This comparator thus works on UNSIGNED integers only. Even worse, 
negative numbers are mapped to positive infinity, which is obviously > 
500! There is your problem. I remember that issue was reported some time 
ago by someone else too.

To solve your problem, you need to check for the negative sign first. E.g.:

require ["comparator-i;ascii-numeric","relational"];
if allof(
         not header :matches "x-spam-score" "-*",
         header :value "ge" :comparator "i;ascii-numeric" "x-spam-score" 
"500")
{
   discard;
   stop;
}

Or, even better: start using the spamtest(plus) extension.

Regards,

Stephan.









More information about the dovecot mailing list