要約

  • :raw は未復号の表現、:content は選択した MIME part、:text は実装の best-effort text を検索する。同じメールに全実装共通の本文はない。
  • 重要な処分を再現するには、message hash、engine と extractor の version、transform、selector、comparator、変換失敗と省略 part を残す。一致は危険性を、非一致は安全性を証明しない。

メールクライアントは MIME tree を一枚の表示へ折り畳む。フィルターはその前段にいる。外側 header の後に空行がなければ、body test が受け取る string set は空で、空文字を探す test さえ false になる。空の本文が存在することと、本文が存在しないことは違う。

本文がある場合も、transform が先に string を作る。物理行ごとに別々に照合するわけではなく、CRLF を含むこともある。comparator と match type が続き、最後に Boolean が出る。その Boolean だけを保存すると、観測装置を失う。

Raw は人が読まない構造も読む

:raw は未復号 body 全体を一つの item とする。transfer encoding を外さず、multipart boundary や内包 part の MIME header も構造ではなく検索対象にする。周辺環境が拒否しない限り、構文誤りだけで filter を避けてはならない。

従って hit は base64 の並び、boundary token、内側の Content-Type、prologue から生まれ得る。受信表現に octet があった証拠にはなるが、recipient がその語を読んだ証拠にはならない。

全体が一 item なので、wildcard は part-aware transform が切る境界を越える可能性もある。raw から content への変更は同じ問いの高速化ではなく、問いそのものの変更である。

Content は tree の探索範囲を宣言する

:content は MIME type で part を選ぶ。完全な type/subtype は一致する型だけ、type だけならその subtype、空 selector なら全 MIME type を対象にする。slash が先頭、末尾、または複数なら何も選ばない。

探索は multipart と message/rfc822 へ再帰するが、選ばれた各 part は独立して照合される。pattern は MIME boundary を越えられない。画面上で隣り合う二つの語でも、別 part なら一つの連続 pattern にはならない。

multipart container 自体を選ぶと prologue と epilogue が別 string になる。nested message を選ぶと内側 header が一 string になり、その body は自分の type が選ばれたときだけ対象になる。どの branch から hit したかを抜きに結果は説明できない。

engine は標準的な transfer encoding を decode し、対応 charset を UTF-8 にする。しかし変換できない part は US-ASCII 扱い、省略、local convention のいずれも許される。false は「なかった」ではなく「比較に入らなかった」かもしれない。

Text は installed capability に依存する

:text は best-effort 抽出であり、transform を書かなかった場合の default でもある。単純な実装は :content "text" と同じにできる。高度な実装は markup を除き、独自 document を変換し、image に OCR をかけられる。出力 string 数まで統一されていない。

そのため、library upgrade や provider migration が policy change になる。新しい converter が attachment の語を初めて可視化し、OCR の変更が以前の hit を消す。Sieve source の差分はゼロでも、観測面の差分はゼロではない。

改良を止める必要はない。依存を versioning すればよい。extractor、capability、warning、omitted part、output hash を持たない記録は、後で再現できない verdict である。

Security の意味を Boolean に載せない

RFC 自身が、raw string match は意図より広くなり得て、text match は spam、virus その他 security filter の代替ではないと警告する。悪用された body matching が他ユーザーへの denial of service を起こさないよう、容量制限も要求する。

包装の token で正当な mail を捨てる false positive と、非対応 attachment を見落とす false negative は、同じ body 機能から生じ得る。hit/miss だけではどちらの経路か分からない。

RFC 5229 の既存記事が扱う variable と capture は別問題である。body wildcard は ${1} などを side effect で設定しない。これは hidden memory を防ぐが、抽出面を完全にはしない。

出典