符号化語

encoded-word (MIME)

[61] encoded-word は、電子メールMIMEヘッダーで用いられる、文字列符号化のための構文です。

[62] 電子メールヘッダー非ASCII文字を安全に取り扱うための構文として開発され、 MIME の一部となりました。

仕様書

構文

   encoded-word = "=?" charset ["*" language] "?" encoding "?" encoded-text "?="
     ; RFC 2231 では「"?" encoding」欠落。 http://www.rfc-editor.org/errata.html
   charset   = <registered character set name>       ; RFC 2047 では token
   language  = <registered language tag [RFC-1766]>  ; RFC 2047 では token
   encoding  = token   ; see section 4
   token     = 1*<Any CHAR except SPACE, CTLs, and especials>
   especials = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "
               <"> / "/" / "[" / "]" / "?" / "." / "="
   encoded-text = 1*<Any printable ASCII character other than "?"
                     or SPACE>
                  ; (but see "Use of encoded-words in message
                  ; headers", section 5)

変換例

=?us-ascii?q?ABC?=

「ABC」

"=?us-ascii?q?ABC?="

「"=?us-ascii?q?ABC?="」

構造化領域では、 quoted-string 内で encoded-word は使えない。非構造化領域では、隣接文字と WSP で離す必要がある。

" =?us-ascii?q?ABC?= "

構造化領域で word の代わりに phrase の一部として出現する 時は「" =?us-ascii?q?ABC?= "」。 comment や非構造化領域では 「" ABC "」 。

(=?us-ascii?q?ABC?=)

構造化領域 (で comment として認められる) 場合 「(ABC)」。 非構造化領域の場合「(=?us-ascii?q?ABC?=)」。

comment の場合は周りの括弧と encoded-word がくっついても良い。

( =?us-ascii?q?ABC?= )

「( ABC )」。

非構造化領域では周りの文字と離す必要があるので、こうする。 comment では、 RFC 2047 に記述はないが、 WSP がそのまま残ると思われる。 (記述が無いということは、例外ではないということでしょう。)

(=?ISO-8859-1?Q?a?=b)

「(=?ISO-8859-1?Q?a?=b)」。

非構造化領域では周りの文字と離さないと encoded-word にならない。 comment では「b」と離さないといけない。

(=?ISO-8859-1?Q?a?= b)

comment の場合 「(a b)」。非構造化領域では 「(=?ISO-8859-1?Q?a?= b)」。

=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=

「ab」。

encoded-word 間の (F)WSP は無視される。

=?ISO-8859-1?Q?a_b?= あるいは

  1. ?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=

「a b」。

encoded-word 間に当たる場所に WSP を入れるには、 どっちかの encoded-word に含めるか、一つにまとめる。

=?us-ascii?q?ABC?=, =?us-ascii?q?DEF?=

「=?us-ascii?q?ABC?=, DEF」

構造化領域で phrase 内の word の代わりであっても、 encoded-word との区切りに WSP が必要。

=?us-ascii?q?ABC?=DEF

「=?us-ascii?q?ABC?=DEF」

同じく。

=?us-ascii?q?ABC?= DEF

「ABC DEF」。

これは正しく復号できる。

=?us-ascii?q?ABC?==?us-ascii?q?DEF?=

「=?us-ascii?q?ABC?==?us-ascii?q?DEF?=」。

RFC 2047 の解読処理手順に従うとまず長い一つの encoded-word と 考えるが、 encoded-word 文法に合致しないので、普通の文字列とする。

=?us-ascii?q?ABC DEF?=

「=?us-ascii?q?ABC DEF?=」。

encoded-word 文法に合致しない。

encoded-word の出現場所とそれにまつわる問題

[64] application/x-kddi-auc

空白間隔の取り扱いの問題

[2] 空白間隔の扱いについて色々問題が。 「ABCあいう」という文字列があるとき、これを符号化するには「ABC」も含めないと、間に間隔が入ったり入らなかったり。

[3] encoded-word の周りの間隔についての話は RFC 1342 に無くて、その時以来の実装や手抜き実装は間隔を (無視していけないのに) 無視したり (無視しないといけないのに) 無視しなかったりする。 しかも単語中だろうがお構いなしにする (RFC 2047 的には妥当だが。) から、 Subject 中になぜか間隔があって、しかも返信するごとにそれが増えていったりする。

特に、折畳みの問題

  • [1] Opera 6.05 の MUA を使っていて、一覧を見てて最近は Subject:欄書かないとかちょんぎれてるとかの人が多いんだなーと思ってたら、メッセージ表示欄にはちゃんと Subject が出てました。つまり、 encoded-word なんかを使ったせいで長くなってしまって折り返しているのを、 plain text 的に最初の行だけ取り出して一覧に表示したから、変に短い Subject だったり 「Re:」だけだったりに見えたんです。昔はこういう MUA やニュース・リーダーが多かった (しかも表示だけじゃなくてそのまま並べ替えて壊すやつとかもいた) んですけど、今でもあるとは驚き!

comment と encoded-word

[7] comment 内の encoded-word の解読は厄介。 quoted-pair の unquote と encoded-word の解読のどちらを先にするか。 pair を先にすると encoded-word もどきが出てくる可能性がある。 word を先にすると pair もどきが出てくる可能性がある。だから両方一度にまとめるしかない。

[8] comment 内の encoded-word は linear-white-space で他の ccontent と離すことになっている。でも RFC 822 では comment 内に lws は出現しないはずだ。 (0x09 や 0x20 は ctext に含まれる。)

[9] >>8 上記の解釈は(たぶん)誤り。 ctext は linear-white-space (SP や HTAB そのもの ではなく) を包含している。 RFC 2822 では ctext から lws を追い出して、 ccontent に FWS を入れてもいいと明示。 See comment(注釈)

[10] comment 内の encoded-word は「(」「)」とくっつけることが出来る。 では、 nest した comment の外側とはくっつけることが出来るのか。 (例>>11)

  • [11] (foo (hoge)=?us-ascii?q?aiueo?= bar)

RFC 2047 には明記はない。 BNF は linear-white-space については当てにならない。 考え方としては、 encoded-word のすぐ外側の括弧にはつけることが出来るとするのが自然と思われる。 つまり >>1 は不正であって encoded-word ではない。

  • [22] 電子メイルでは RFC822/RFC2822/MIME 構造化頭欄の注釈以外に、 DSNMDN の構造化欄の注釈でも使えます。
  • [30] >>11 が言いたいことはよくわかんないけど、 RFC 2047 の解読算法解説を参考に考えると、 >>11 は不正な可能性があるな。
  • [31] >>30 まあとにかく、 )=? はしないほうがいいってこった。

[47] でも encoded-word の本来の意図は非ASCII文字を含む 「word にしたいもの」を RFC 822atom になるように符号化することでしょうから、 まず RFC 822 に従い字句解析を行い、その結果が encoded-word の構文に合致すれば復号するというのが本来の意図に沿った動作でしょう。

それに従えば、 >>11 の例も復号されてしかるべきだと思います。

encoded-word が使える電子メイルの欄

[12] RFC 2047 には次のような記述がある。

  • 「encoded-word」は「addr-spec」のどこにも出現してはいけません
  • 「encoded-word」は「quoted-string」中に出現してはいけません
  • 「encoded-word」は Received (受信) 頭領域中で使用してはいけません
  • 「encoded-word」は MIME Content-Type (内容型), Content-Disposition 領域の parameter 中や「comment」や「phrase」内を除くどの構造化領域本体でも使用してはいけません

この直前には、非構造化領域 (*text), comment, phrase 中の word の置き換え としてのみ encoded-word が使える、と書いてある。 その補足が上記の表なんだけど。疑問点:

  • Received: 領域の comment で encoded-word を使っていいのかどーか。

わざわざ注記してあるってことは、例外で使ってはいけないのかもしれないし、 あるいは単なるミスなのか。

  • [26] RFC2557 (MHTML) は、電子メイルで使われる Content-Location:欄について、不正な URI が使われる場合 (例えば SP を含む場合も。) には encoded-word を使わなければならず、解読しなければなりません。 (4.4.1, 8.2)
  • [32] >>12 RFC2821 なんかでは comment 内の書式も決めてる関係かもしれないとも思うが、よくわからんのう。
  • [33] 2003-01-05 08:59 US-ASCII: RFC822 拡張構造化欄に該当するものの中身である "(" ... ")" は、必ずしも comment とは限りません。例えば Content-Features: 欄は全部注釈・・・であるはずがないでしょ? (ちょっと前の ietf-822 の話題。)

HTTP において encoded-word が使える場所

[6] RFC 2616 までは符号化語HTTP ヘッダーの一部で使えることになっていました。 しかし実際には誰も実装していませんでした。この規定は RFC 723x では削除されています。

[13] RFC2616 (HTTP/1.1) によると、

TEXT

[15]

The TEXT rule is only used for descriptive field contents and values that are not intended to be interpreted by the message parser. Words of *TEXT MAY contain characters from character sets other than ISO-8859-1 [22] only when encoded according to the rules of RFC 2047 [14].

TEXT 規則は記述的な欄内容及び値であってメッセージ解析器により解釈されることを意図していないものににも使うことが出来ます。 *TEXT の言葉は、 RFC 2047 の規則に従って符号化される場合に限って ISO-8859-1 以外の文字集合の文字を含めても構いません。 (RFC 2616 2.2)

  • TEXT = <any OCTET except CTLs, but including LWS>

>>14 RFC 2616 の「メッセージ解析器により解釈されることを意図していないもの」 をどう解釈するのが良いのか分かりませんが、とりあえず TEXT が使われているのは、

です。このうち quoted-string で使えるのはどんなもんかと思いますな。

  • [18] >>17 で別途明記されている warn-text として使われる以外の場合, 特に parameter の value として使われる場合については明記がありませんねえ。
  • [20] RFC2068 (HTTP/1.1) でも同様に規定されています。 RFC1945 (HTTP/1.0) では encoded-word には触れていません。 (その代わり TEXT にはどんな8ビットの文字コードも使えました。)
  • [21] ちなみに、 RTSPSIPencoded-word には触れていません。 UTF-8 を使っていますし、使えないのでしょう。

warn-text

[17] >>16 Warning:欄で使われる warn-text = quoted-string は「If a character set other than ISO-8859-1 is used, it MUST be encoded in the warn-text using the method described in RFC 2047 [14].」と、 >>15 同様に規定されています。

  • [19] RFC 2068 (HTTP/1.1) でも同様に規定されています。 RFC 1945 (HTTP/1.0) には Warning: 欄はありません。

言語指定

[35] RFC 2231encoded-word の構文が拡張され、 charset の後に *言語タグを指定できるようになりました >>51, >>56

[52] 次の例 >>51 は、符号化された部分の言語EN であることを表しています。

From: =?US-ASCII*EN?Q?Keith_Moore?= <moore@cs.utk.edu>

[53] 一つの encoded-word では1つの言語しか指定できませんが、 encoded-word の長さは任意に短くできるので、 文字列の任意の部分に任意の言語タグを指定することができます。

[54] ただしオーバーヘッドは劇的に増加します。また encoded-word 間の空白の取り扱いは相互運用性が高くないので、実装によっては言語の区切れ目に空白が現れたり、 返信を繰り返すうちに空白がどんどん増えていったりする危険性もあります。

[36] ietf-822ietf-useforMIMEr は、生 UTF-8 header なんて認められん、 encoded-word の言語指定の分情報損失じゃないか、と言ってます。

それに対して CharlesLindsey は、どうしても使いたいんなら Unicode 言語タグでも使ってろホ゛ケェと言ってます。 MIME'r よ、お前ら単に7ビットと言いたいだけちゃうんかとか、言語タグとか本気で言ってるのかこの Unicoder めとか、そういう話は置いといて、実際に言語指定に対応した UA とか、言語指定が付いたメッセージなんてどれだけ存在するのか。

mail-people は特に何も言ってこないし、 Charles はあったとしても日本か中国くらいじゃない? と言っている。 しかし日本でも中国でも、言語指定のあるメッセージなんて見たことが無いよね。 1468bis は ISO-2022-JPencoded-word で言語指定は使うなとまで言っているのでして。

そもそも日本のほとんどの実装は、 encoded-word 対応といっても ISO-2022-JPB 符号化にしか対応してないのが普通だったりもしますからな。 (ひどいのになると、 ISO-2022-JPB の大文字・小文字の区別をしないのとかもある。)

[37] ということからして、この世界に実質的に encoded-word の言語指定なんて使ったメッセージは存在しないのでは、と強く疑われます。

[38] >>37 manakai みたいに言語情報をちゃんと扱える UA は他にもあるはずだけど、それを有意義に使えているかどうか。 (manakai は捨ててる同然だし、生成の時には使えないし。)

[39] >>38 生成側としては、言語情報をそもそも持っていなければつけようが無い。 で、言語情報は実質的に利用者に指定させるしか得る方法がない。 (IM と連携して云々とか考えられるけど、現状では無理だな。)

文脈を検討せずに、設定から自動で得て文字列全体に適用する (conneg 設定の流用とか。) のだと、 日本語れんしゅうちゅう。en とかつけかねないし、きめ細かい実装がないとかえって有害。

[40] 構文解析とか、そういう苦労して言語情報つけた割に得られ得る利点が CJK glyph selection くらい (それもたいして役に立たない。) だと、やっぱり実装する気になんてならないよなあ。

その他実装について

符号化は面倒。特に ISO-2022-JP だったりすると、

とかやややっかいだったり。

[41] encoded-word で符号化された中身は基本的に何でもありなので、実装は勝手な仮定をしてしまわないように注意する必要があります。

たとえば、 encoded-word で符号化した中身に改行が含まれていることも十分あり得ます。それを想定していない MUA だと、たとえば Subject の表示の際に画面が乱れる虞があります。 (厳密には RFC 822 では quoted-pair を使って改行を生で表現できますが、まともに使えるかは不明です。ですから多くの MUA は unfold した欄本体に改行が含まれることを想定していないと思われます。)

[55] RFC 2231 は将来文字コードレベルで言語の指定ができるようになるので、 その場合はより柔軟に指定できるそちらの方法を MIME レベルの指定の方法よりも利用するべき >>51 としていましたが、そのような方法は後に取り下げられています。

RFC 2482 を参照。

実装

[65] perl-mailutils/Encoder.pod at master · wakaba/perl-mailutils, https://github.com/wakaba/perl-mailutils/blob/master/lib/EncodedWord/Encoder.pod

歴史

HTTP における encoded-word

[48] RFC 2616 までは HTTP でも一部で encoded-word が使えることになっていましたが、実際には誰も使っていませんでした。

[58] RFC 2231HTTP への適応について規定する RFC 5987 は、 encoded-wordHTTP における利用には疑問がある >>57 として、 encoded-word の拡張は採用していません。

[49] RFC 723x でこの規定は完全に削除され、現在では HTTP では encoded-word は使われていません。

[50] ただし HTTPmultipart/* によって MIME実体を埋め込む場合、 その実体MIMEヘッダーでは encoded-word を使うことに (理論上は) なります。しかしこちらもやはり使われていません。

[59] Content-Disposition: ヘッダーfilename 引数の値として encoded-word を使う方法は Firefox で実装され、広く使われていましたが、後に削除されました。

めも

[42] Thunderbird 1.5 には、 Atom で題名に encoded-word のような文字列を使うと、 勝手に復号してしまうという不具合があります。 (Thunderbird 1.5 は Atom822 に変換して処理していますが、その際に Subject: に入れる文字列に encoded-word のような文字列が含まれていることを想定していないようです。) (名無しさん 2006-07-22 04:14:28 +00:00)

[43] encoded-wordquoted-string 内で認められないのはなぜか?

  1. 元々 quoted-string は (引用符と \LWS 以外) 文字は (文字通り) 文字通りの意味を持つというものだから、 encoded-word として解釈させようというのはおかしい。
  2. encoded-word は人間向けで、 機械向けではない。機械向けの場所でも認めるとすると正規化など問題が難しくなる。

で、 filename の場合、 そもそももともとこれはヒントなので、その値を参考にファイル名を決める手段として、 encoded-word のようなものを復号するのもありじゃないの? と Keith Moore はいってます。

(名無しさん 2006-08-13 07:27:23 +00:00)

[44] NAS (RFC 4707) は、 UseforRFC 化されるまで、と断りながらも son-of-RFC 1036 と同じ、 encoded-word が使える (実際にはまったく使われていない) ニュースグループ名の構文を採用しています。

(名無しさん)

[45] JavaScript で MIME ヘッダをデコード - bkブログ (2007-10-07 23:20:17 +09:00 版) http://0xcc.net/blog/archives/000185.html (名無しさん)

[46] JavaScript で MIME ヘッダをデコード - bkブログ ( 版) http://0xcc.net/blog/archives/000185.html

[823] fmlSubject:encoded-word をいったん復号して ISO-2022-JP符号化しなおします。このとき ISO-2022-JP として表せない文字があると、 復号したまま放置するので、結果として文字化けすることがあります。

[824] RFC 6857 - Post-Delivery Message Downgrading for Internationalized Email Messages ( ( 版)) http://tools.ietf.org/html/rfc6857#section-6

[60] draft-klensin-encoded-word-type-u-00 - The "U" Encoding for Encoded-Words in Email ( 版) https://tools.ietf.org/html/draft-klensin-encoded-word-type-u-00

[63] メールの送信元を完璧になりすます「Mailsploit」は何が危険か – 無能ブログ () https://blog.cheena.net/2017/12/07/%E3%83%A1%E3%83%BC%E3%83%AB%E3%81%AE%E9%80%81%E4%BF%A1%E5%85%83%E3%82%92%E5%AE%8C%E7%92%A7%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%99%E3%81%BE%E3%81%99%E3%80%8Cmailsploit%E3%80%8D%E3%81%AF%E4%BD%95%E3%81%8C/