Subject: [sieve] Sieve deleteheader and :count match type

From: Ken Murchison <[email-masked]>
Date: Mon, 16 Jan 2017 19:39:12 -0500

Does :index still behave in the same way with the :count match-type that 
it does with :value, :is, :regex, etc?

In other words, would the following delete the second instance of the 
X-foo header if, and only if, there are 3 or more instances?

deleteheader :index 2 :count "ge" :comparator "i;ascii-numeric" "X-foo" 
[ "3" ]

-- 
Kenneth Murchison
Principal Systems Software Engineer
Carnegie Mellon University

---

From: [email-masked]
Date: Mon, 16 Jan 2017 18:11:29 -0800 (PST)

> it does with :value, :is, :regex, etc?

That depends on the context. :index is associated with multiple extensions;
its meaning depends on which one you're talking about.

For example, the index extension only specifies how :index works with the
header, address, and date tests. Note that these are tests, not actions, and
the interpretation of the combination of :index and :count is pretty clear
given the "number of specified entities" language in RFC 5231 section 4.2:
:index restricts the test to Nth field, adding :count to that basically then
gives you a 1 or 0 depending on whether or not there is an Nth field, which is
what is tested. (And in the case of the date test, it's further restricted to
fields containing valid dates.)

In other words, these two tests are basically equivalent:

   header :index 4 :count "gt" :comparator "i;ascii-numeric" "foo" "0"

   header :index 4 :matches "foo" "*"

Personally, I think the second test is much clearer, but YMMV.

The :index that's part of deleteheader action isn't part of the index
extension, but works pretty much the same way: It restricts the entire
operation to the Nth field. And in this case the specification is very clear
(secion 5, fourth paragraph) that the <value-patterns> check, which would
necessarily include :count, happens *after* the :index restriction is applied.

And this means that

   deleteheader :index 2 :count "ge" :comparator "i;ascii-numeric" "X-foo" [ "3" ]

is a no-op, because the :index restriction is applied first, and means that the
number of fields under consideration is either 0 or 1, and can be >=3. And that
makes the addition of :count to :index useless in this context.

But more generally, the :count match type really only makes sense in the
context of tests or actions on at most one thing. It sort of falls apart in the
context of action that's acting on multiple things, because it makes sense to
apply the test part of an action on a case by case basis to the set of
things the action is being applied to, and use that result to control whether
or not to apply the action.

But the semantics of :count are "count the number of things and then test
that". And while that plays fairly nicely with tests, it's really at odds
with action semantics.

More generally still, since :count is wierd, the accepted convention is for new
actions and tests to specify how :count works for them. RFC 5260 does this for
both currentdate and date. RFC 5703 explains how :count and :mime interact. And
so on.

But editheader didn't do that for deleteheader, and that IMO means the behavior
of :count in the context of deleteheader is undefined unless :index is also
present, in which case it's useless.

I also don't think that saying that :count tests perform a preliminary count
like :index :last is especially useful - can you think of a case where you'd
want to delete all headers of a given type based on how many of them are
present? I can't.

				Ned

---

From: Ken Murchison <[email-masked]>
Date: Tue, 17 Jan 2017 07:13:26 -0500

Hi Ned,

> want to delete all headers of a given type based on how many of them are

No I can't, which is why I started thinking about the semantics of 
:count with deleteheader.  I'm fine making it a no-op or a syntax error.

---

From: Arnt Gulbrandsen <[email-masked]>
Date: Tue, 17 Jan 2017 12:20:13 +0000

> want to delete all headers of a given type based on how many of them are 

It's far-fetched, but deleting both subject fields if there are two or 
more? I think most people choose to use the first. Choosing to delete both 
isn't entirely unreasonable, though.

The same applies to other header fields that may occur at most once.

Arnt

---

From: [email-masked]
Date: Tue, 17 Jan 2017 08:47:39 -0800 (PST)

> isn't entirely unreasonable, though.

I don't really see a case for deleting all of them. Deleting all but one
makes a certain amount of sense, but you can't do that directly with
a single deleteheader action.

> The same applies to other header fields that may occur at most once.

Again, all but one, sure, or maybe appending them to each other. But not
full deletion.

				Ned

---

From: Arnt Gulbrandsen <[email-masked]>
Date: Tue, 17 Jan 2017 18:11:22 +0000

Ned Freed writes:
> I don't really see a case for deleting all of them.

FWIW, the messages I saw with two subject fields (back when I cared about 
such things) had two misleading/garbage/bad subject fields, not one with a 
bad value and one with an appropriate value.

My choice was to keep the shortest syntactically valid subject. But based 
on the data I saw I considered deleting both to be a defensible option.

> Again, all but one, sure, or maybe appending them to each other. But not 

I see I also analysed messages with two content-type, 
content-transfer-encoding, message-id and date fields, but don't seem to 
have seen any where deleting both was appropriate.

Arnt