要約

  • RFC 5231 は、Sieve の address、envelope、header テストに順序比較の :value と個数比較の :count を加えた。:count の単位は、どのテストがメッセージを読むかで変わる。
  • address はメールボックス要素、envelope は配送アドレス、header はフィールドの出現数を数える。envelope :count の to は実行中の利用者だけを示す。

「宛先はいくつか」は一つの問いではない

メールの To: 行を見れば、宛先を数えるのは簡単に思える。二つのメールボックスがあれば二人の宛先だ、と。しかしメールフィルターが扱うのは行の見た目ではない。メッセージヘッダー、SMTP の配送エンベロープ、解析済みのアドレス構造は、それぞれ異なる情報と権限を持つ。

2008年1月に公開された RFC 5231 は、Sieve の既存の address、envelope、header テストへ関係比較を導入した。値が一致するかだけでなく、比較値より大きいか、小さいか、等しいか、異なるかをスクリプトで問えるようにした。追加されたマッチ型は二つある。:value は整列情報を返す比較器で値を比べ、:count は選択された要素を数えてから比較する。

演算子は gt、ge、lt、le、eq、ne。:value では、メッセージから得た値が左辺、スクリプトのキー一覧の値が右辺となる。両側に複数の値がある場合、一組でも条件を満たせばテストは真になる。比較器が変われば順序の意味も変わるため、これは単なる自然言語の「大小」ではない。実装は i;ascii-numeric をサポートしなければならず、少なくとも32ビットの符号なし整数を扱う。この比較器では負数を表せない。

より興味深いのは :count だ。To: にメールボックスが二つ、Cc: に一つあるとしよう。address :count が to と cc を調べれば、数えるのは三つのメールボックス要素である。グループ名そのものは加算されないが、グループ内のメールボックスは数える。一方、header :count で to と cc を指定すると、数えるのはヘッダーフィールドの出現数だ。通常の RFC 2822 準拠メッセージに To: と Cc: が一つずつあれば、結果は三人ではなく二行になる。

envelope :count はさらに別のもの、選んだ配送エンベロープ部分にあるアドレスを数える。to エンベロープには常に一つ、すなわちその Sieve スクリプトを実行している利用者のアドレスだけが入る。他の人への配送を利用者が推測できないよう、仕様がそう定めている。from は SMTP の MAIL FROM が空ならゼロ、それ以外なら一つだ。したがって「宛先数」は、ヘッダーに見えるメールボックス、スクリプトに開示された配送先、ヘッダー行数のどれを指すのかを先に決めなければならない。

この違いは条件の組み合わせ方にも及ぶ。to と cc をまとめたアドレス数は、両方のメールボックス数を足す。「To が3件以上、または Cc が3件以上」という規則にしたいなら、別々の比較を anyof に入れる必要がある。合算カウントは「両方合わせて3件以上」という別の問いに答える。RFC の例でも、To が2件、Cc が1件なら合算のしきい値判定は真だが、別々に3件以上を問う二つの条件はいずれも成立しない。

RFC 5231 が関係演算をゼロから発明したわけではない。2002年の RFC 3431 がすでに拡張と二つのマッチ型を導入しており、RFC 5231 はそれを置き換えた。後継仕様は比較器の参照を RFC 4790 のインターネットアプリケーション照合レジストリーに改め、例を訂正し、COUNT が数える RFC 2822 の要素を明確化した。また、より広い空白除去要件が Sieve 本体へ追加された後に、独自の空白除去規則を取り除いた。IANA の Sieve Extensions レジストリーには relational 能力として登録されている。

ただし拡張は検査で止まる。暗黙の KEEP や fileinto、redirect、reject などの明示的な動作を変えない。述語はスクリプトの分岐を決められるが、サーバーが何を解析したか、分岐を正しく実行したか、最終的にどこへ配送されたかまでは証明しない。比較の単位、比較器、実装面が分かれていることが、精密な言語仕様の効用と限界を同時に示す。

出典