[Dovecot] Sieve "header :value" test does not work

Stephan Bosch stephan at rename-it.nl
Wed Sep 7 16:48:04 EEST 2011


On 9/7/2011 2:40 PM, Tom Hendrikx wrote:
> The above snippet poses some other issue that I cannot easily solve: the
> ascii-numeric comparator only handles integer values.
>
> All 0.xxxx header values are truncated to 0 by the comparator, just like
> the sieve script value "0.95". After comparision, this results in true
> for all cases.
>
> I don't really see a way to interact with floats in sieve, other than
> using regular expressions. However this gets clumsy/hairy quite fast
> when you're matching a hypothetical header value>=0.73 in stead of>=0.99.
>
> Any ideas?

Yes. This can be a problem. However, the usual application for this is 
matching against a spam header. If it is, you can use the spamtest 
extension instead. Then you can configure the gory details in the 
background 
(http://wiki2.dovecot.org/Pigeonhole/Sieve/Extensions/SpamtestVirustest).

Otherwise, things indeed tend to get hairy. I've puzzled a bit and came 
up with the following:

====
require "variables";
require "relational";
require "comparator-i;ascii-numeric";
require "regex";

# Extract integer and fractional part separately:
set "val_int" "0";
set "val_frac" "0";
if header :regex "X-Header-Name" "([0-9]+)\\.([0-9]+)" {
   set "val_int" "${1}";
   set "val_frac" "${2}";
}

if allof (
   /* Compare the integer part */
   string :comparator "i;ascii-numeric" :value "ge" "${val_int}" "5",
   /* Compare the fractional part */
   string :value "ge" "${val_frac}" "34" ) {
   discard;
}
====

As you can see, the integer and fractional parts of the fractional 
number are extracted separately using a :regex match. Then the 
comparison is performed. The integer part is compared using 
i;ascii-numeric. Quite counter-intuitively, the fractional part is 
compared using a normal string comparison. The earlier regex match made 
sure that the ${val_frac} variable only contains digits. The string 
comparison makes sure that the length of the fractional part does not 
matter (much) and that the comparison works as expected. A length 
difference will only have an effect when there are spurious trailing 
zeros and all the preceeding digits are equal, thereby causing the 
longer string to have higher value, which is not strictly correct.

The above certainly does not deserve an award for beauty, it does not 
handle negative numbers (can be added), and it is not tested very well.  
So, use this with caution. Unfortunately, there is no i;ascii-fractional 
(or whatever) collation and afaik nothing like that is in the works at 
the IETF.

Regards,

Stephan.








More information about the dovecot mailing list