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

2011-09-07 Thread Stephan Bosch

On 9/7/2011 4:17 PM, Tom Hendrikx wrote:

Thanks for the idea :)
My first alternative way of thinking was to put the header value in a
variable, then multiply it by 1 (in my actual issue, the fraction
always has 4 characters), then handle it as an int. However, doing a
calculation is also not supported.

I was trying to do some nifty stuff with DSPAM headers, which adds
header that indicates "Spam" or "Innocent", and a fractional value
between 0 and 1 that indicates the confidence that the filter has in its
own classification:

X-DSPAM-Result: Spam
X-DSPAM-Confidence: 0.9456
==>  quite sure it is spam

X-DSPAM-Result: Innocent
X-DSPAM-Confidence: 0.9889
==>  even more sure that it is not spam

Based on these headers, I wanted to do something with messages that the
filter was really sure about, like pushing them to spamcop.

Combining these headers in the sieve spamtest configuration to create a
sliding scale between 1 and 10 is not really possible.

Not with the current implementation, no. But  I could incorporate this 
new type of specification in the configuration capabilities. Using the 
spamtest :percent test, this could for instance map as follows:


Result=Innocent; Confidence=0. - 1. => spamtest :percent yields 
50 - 0
Result=Spam; Confidence=0. - 1. => spamtest :percent yields 50 - 
100


Other mappings are possible of course.

Regards,

Stephan.




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

2011-09-07 Thread Tom Hendrikx
On 07/09/11 15:48, Stephan Bosch wrote:
> 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. 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.
> 

Thanks for the idea :)
My first alternative way of thinking was to put the header value in a
variable, then multiply it by 1 (in my actual issue, the fraction
always has 4 characters), then handle it as an int. However, doing a
calculation is also not supported.

I was trying to do some nifty stuff with DSPAM headers, which adds
header that indicates "Spam" or "Innocent", and a fractional value
between 0 and 1 that indicates the confidence that the filter has in its
own classification:

X-DSPAM-Result: Spam
X-DSPAM-Confidence: 0.9456
==> quite sure it is spam

X-DSPAM-Result: Innocent
X-DSPAM-Confidence: 0.9889
==> even more sure that it is not spam

Based on these headers, I wanted to do something with messages that the
filter was really sure about, like pushing them to spamcop.

Combining these headers in the sieve spamtest configuration to create a
sliding scale between 1 and 10 is not really possible.

-- 
Regards,
Tom


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

2011-09-07 Thread Stephan Bosch

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. 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.







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

2011-09-07 Thread Tom Hendrikx
On 06/09/11 21:21, Tom Hendrikx wrote:
> On 06/09/11 21:11, Tom Hendrikx wrote:
>> hi,
>>
>> After following some examples and searching for sieve samples in this ml
>> history, I'm quite sure that the following sieve snippet should give no
>> surprises:
>>
>> if header :value "ge" :comparator "i;ascii-numeric" "X-Header-Name"
>> "0.99" { /* do something */ }
>>
>> However the Pigeonhole Sieve 0.2.3 on dovecot 2.0.14 gives me following
>> error:
>>
>> test: line 3: error: unknown tagged argument ':value' for the header
>> test (reported only once at first occurence).
>> test: error: validation failed.
>>
>> What obvious mistake am I failing to see here?
>>
> 
> To answer my own question (which was found by grepping through
> /usr/share/doc/dovecot-2.0.14/sieve/rfc/*bz2): including the
> "relational" extension in the "require" statement adds support for this
> test.
> 
> Sorry for the noise :/
> --
> Tom
> 

The above snippet poses some other issue that I cannot easily solve: the
ascii-numeric comparator only handles integer values.

All 0. 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?

-- 
Regards,
Tom


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

2011-09-06 Thread Tom Hendrikx
On 06/09/11 21:11, Tom Hendrikx wrote:
> hi,
> 
> After following some examples and searching for sieve samples in this ml
> history, I'm quite sure that the following sieve snippet should give no
> surprises:
> 
> if header :value "ge" :comparator "i;ascii-numeric" "X-Header-Name"
> "0.99" { /* do something */ }
> 
> However the Pigeonhole Sieve 0.2.3 on dovecot 2.0.14 gives me following
> error:
> 
> test: line 3: error: unknown tagged argument ':value' for the header
> test (reported only once at first occurence).
> test: error: validation failed.
> 
> What obvious mistake am I failing to see here?
> 

To answer my own question (which was found by grepping through
/usr/share/doc/dovecot-2.0.14/sieve/rfc/*bz2): including the
"relational" extension in the "require" statement adds support for this
test.

Sorry for the noise :/
--
Tom


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

2011-09-06 Thread Tom Hendrikx
hi,

After following some examples and searching for sieve samples in this ml
history, I'm quite sure that the following sieve snippet should give no
surprises:

if header :value "ge" :comparator "i;ascii-numeric" "X-Header-Name"
"0.99" { /* do something */ }

However the Pigeonhole Sieve 0.2.3 on dovecot 2.0.14 gives me following
error:

test: line 3: error: unknown tagged argument ':value' for the header
test (reported only once at first occurence).
test: error: validation failed.

What obvious mistake am I failing to see here?

--
Tom