[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