要約

  • RFC 1556は双方向テキストの表示責任を三つに分けた。visualでは作成側が見た目の順序を用意し、implicitでは表示アルゴリズムが解決し、explicitでは本文中の制御列が方向を指示した。
  • MIMEが非ASCII文字を保ったことは、受信者が意図した読む順序を再現した証明ではない。charset、方向方式、制御列、レンダラーの文脈は別々の証拠である。
  • 1993年12月の文書はInformationalであり、Internet Standardではなかった。後年のHTML、Unicode、UTF-8メールは境界の持続を示すが、RFC 1556からの直系や、その方式の普及を証明しない。

「届いた」の後に、もう一つの処理があった

古いメールを復元するとする。元ファイルと保存物のハッシュは一致し、MIMEの復号も成功した。文字は一つも欠けていない。ところが、ある閲覧ソフトではラテン文字の名称が数字の左に現れ、別のソフトでは右に現れる。コピーすると句読点まで移動する。

配送の証拠が誤っているわけではない。その証拠が答える範囲が狭いのである。受信した文字列を一行の像にするには、段落の基準方向、逆方向の区間、中立的な記号、数字、改行位置を決めなければならない。

RFC 1556の題名は Handling of Bi-directional Texts in MIME。Hank Nussbacherが1993年12月に発表した。RFC Editorの記録とIETF DatatrackerはいずれもInformationalに分類し、本文もInternet Standardを定めるものではないと明記する。

提案はMIMEの双方向テキストにdirectionの約束を与えるという限定的なものだった。だが、その背後には大きな区切りがある。表現をそのまま運ぶことと、人間が見る順序を一意に決めることは同じ作業ではない。

MIMEはまず文字を旅させた

RFC 1521は、メール本文を平坦なASCIIだけの世界から広げた。body partはmedia typeとcharsetを示し、Base64やQuoted-Printableで古いメール基盤を通過できた。RFC Editorの情報ページはMIME Part Oneの歴史的位置を記録している。

RFC 1522は一部ヘッダーにも非ASCII表現を導入した。作成ソフトがencoded-wordを作り、対応するreaderがそれを認識し、符号化を戻して指定charsetで表示する。同文書の情報ページはヘッダー拡張としての範囲を示す。

charsetは値と文字の対応を説明し、transfer encodingは値を経路上で守る。しかし、ISO-8859-6のアラビア文字やISO-8859-8のヘブライ文字がラテン文字と同じ行に入ると、文字の身元だけでは画面上の隣接関係が決まらない。

RFC 1556はMIMEの失敗を指摘したのではない。MIMEが成功した地点から、別の証明が必要だと示した。

同時期のヘブライ語メールは「先に並べる」方式だった

NussbacherとYehavi BourvineによるRFC 1555は、同じ1993年12月にMIMEとISO-8859-8を使うヘブライ語メールを記述した。情報ページもInformationalとする。

既定はvisual directionalityだった。ヘブライ語は右から左へ入力されても、左から右に見せるための順番に符号化され、通常のMIMEで左から右に送られた。表示側は内容の方向を知らなくてもよい。作成側が、想定する画面の一列をすでに用意していたからである。

この方式は単純な端末に強い。しかし、保存された並びは「後で再解釈しない」という条件を抱える。visual orderをlogical orderだと思った新しいエンジンがimplicitな並べ替えをすると、すでに済んだ作業をもう一度行う。

RFC 1555は、Listservが短縮ヘッダーを配布し、アーカイブがMIME情報を残さない場合も述べた。符号化済み本文は存在していても、その読み方を示す文脈が失われる。

将来8-bit mailが透明になればtransfer encodingの一部は不要になるが、Content-Typeとdirectionalityは残るとも予測した。経路が広くなっても、表示責任は消えない。

Visual――作成側が表示を完成させる

RFC 1556ではvisualが既定で、通常のISO-8859名を使い、特別なsuffixを付けない。表示アプリケーションは左から右という一つのprimary display directionだけを持ち、内容を単方向テキストとして描く。作成アプリケーションが正しく見える順に文字を用意し、表示時には方向制御も順序計算も使わない。

利点は明快だ。古いreaderでも、理解できない文字列を画面に置ける。だが、簡単になったのは受信側だけである。責任はcomposerへ移り、viewerが賢く並べ直さないことが契約になる。

編集では弱点が出る。カーソル移動、検索、ラテン語の挿入、窓幅の変更、コピーは、文の論理構造ではなく特定画面向けの並びを扱う。改行が変われば、以前の見た目用配置が成立しないこともある。

Visualは方向を無くしたのではない。判断を送信前へ移した。

Implicit――受信側の計算が表示を決める

Implicitを表す候補がISO-8859-6-iとISO-8859-8-iだった。表示順は、文字の種類、隣接文字との位置関係、primary directionを使うアルゴリズムで決める。手順が複雑なため、RFC 1556はECMA TR/53を参照先にした。

作成側はより論理的な順序を保てる一方、受信側は方式を認識し、互換性のあるdirectional propertyを使い、段落の基準方向と境界を与えなければならない。数字、句読点、中立文字は周囲に依存する。どこで行を折るかも結果の入力になる。

共通アルゴリズムは恣意性を減らすが、payload hashの中に出力が含まれるわけではない。ルールの版、基準方向、markupの境界、改行が違えば、同じdecoded sequenceから異なるvisual sequenceが生まれる。

したがって再現には、文字列だけでなく、それを判断した環境が必要だった。

Explicit――見えない命令を二者で守る

Explicit用の名称はISO-8859-6-eとISO-8859-8-e。方向を定めるcontrol sequenceを本文中に挟み、送信側が文脈の開始や変更を明示する方式である。

明示しただけでは保存されない。不可視の制御をsanitizerが削除するかもしれず、converterは値を残してもreaderが意味を知らないかもしれない。作用範囲が正しく閉じなければ、意図しない区間まで影響する。可視文字だけの比較は、最重要の違いを見落とす。

RFC 1556によれば、基礎となったECMA TR/53は三つのcontrol functionを追加し、ECMA-48の既存22機能を変更した。単一の「右から読む印」ではない。方向はactive positionの移動や、data componentとpresentation componentの対応に関わった。

送信側は命令を正しく置き、受信側はそれを保存して状態として実行する。両方が証拠鎖に入る。

データ上の位置と画面上の位置は別だった

ECMA TR/53のdevice modelは、graphic characterとcontrol functionを受け取り、書字慣行に従う人間可読のgraphic imageを作る装置を描いた。そこではdata componentとpresentation componentが分かれ、それぞれのactive positionが異なる規則で動き得る。

この区別が、問題をフォントだけで説明できない理由である。フォントはglyphを選ぶ。presentation modelは、そのglyphが何の隣に置かれ、cursorがどちらへ進み、backspaceやcarriage returnがどの位置に働くかを決める。

RFC 1556はこの深い構造をMIME側の方式選択へ圧縮した。受信側は、完成済みのvisual rowなのか、implicitに解く列なのか、explicitな命令を含むstreamなのかを知らなければならない。選択情報が消えると、正しいデータが誤った表示機械に入る。

文字を失わない四つの故障

第一はmetadata lossである。gatewayがISO-8859-8-iをISO-8859-8へ正規化するか、archiveがContent-Typeを落とす。文字は残り、方式だけが失われる。

第二はdouble reordering。composerがvisual orderを作った後、readerがlogical orderだと仮定してimplicit algorithmをかける。各部品は自分の仕様に従い、組み合わせが誤る。

第三はcontrol stripping。security filterが不可視のexplicit controlを除去する。印刷可能文字だけなら「同じ」と判定されても、順序命令はもうない。

第四はcontext drift。基準方向、行境界、style境界、algorithm revisionが違う二つのimplicit rendererは、同じdecoded sequenceから違うvisual sequenceを作る。

数字や識別子があると、これは見栄えだけの問題ではない。記号が別の金額に寄り、画面では妥当に見える文字列が別順序でコピーされる。全ての文字があることは、関係まで保たれた証明にならない。

後年の仕様は境界を残したが、直系を証明しない

1997年のRFC 2070はHTMLの国際化にDIR属性やBDO override要素を導入した。情報ページが示すように、これはWeb markupの別契約であり、RFC 1556のsuffixを直接実装した証拠ではない。

初期のUnicode Bidirectional Algorithmはlogical memory orderとdisplay orderを分け、directional formatting codeは表示順へ作用すると説明した。現在のUAX #9は大きく発展し、higher-level protocolが与えられる文脈も定義する。

2012年のRFC 6532はend-to-endでUTF-8を扱えるメール環境のheader valueに直接UTF-8を許した。同文書の記録はその独立した範囲を示す。文字の運び方が直接的になっても、memory orderとdisplay orderは同じ層にならない。

これらは境界が繰り返し現れる証拠である。-iや-eの普及、あるいはRFC 1556からUnicode、HTML、SMTPUTF8への一本道を証明するものではない。

一枚のスクリーンショットでは足りない

輸送のreceiptにはoriginal octets、hash、transfer encoding、decoded code-point sequenceを残す。途中で表現が変化したかを答える。

解釈のreceiptにはContent-Type、charset、方向方式、explicit control、base direction、上位markupとstyle、rendererとalgorithm versionを残す。受信側がどの規則を適用したかを答える。

表示のreceiptにはline segmentation、resolved visual order、screenshot、copy/pasteやround tripの結果を残す。特定環境で何が見えたかを答える。

入力のない画像は一度の見た目しか証明せず、出力のないhashは一つの列しか証明しない。テストにはアラビア文字またはヘブライ文字、ラテン文字、数字、句読点、中立文字、入れ子、複数の行幅を含めるべきである。renderer移行時は差が説明できるまで新旧双方を保持する。

文書の公開は運用の現実ではない

Heng LuのRunning-Code Primacyは、今日使える規律を与える。文書は調整物であり、実装、運用、利用が現実を示す。RFC 1556の公開は約束が記録された証拠で、どのメールソフトが実行したかの証拠ではない。

Minimum Initial Specification、Localized Future Decision、Voluntary Adoptionは、共通層に置く最小で決定的、かつ局所検証可能な規則を問う。この事例では、輸送後の文字一致だけでは可読性のinvariantとして弱かった。方式、文脈、表示手続きも検証対象になる。

Reality Layersの観点は、輸送の証拠が表示結果を代弁することを防ぐ。これは後代の語彙であり、NussbacherやECMAの主観を示すものではない。現在の叙述を証拠の範囲に止めるために使う。

誰がすでに並べたのか

Visualではcomposerがすでに行動していた。Implicitではrendererがこれから計算する。Explicitではsenderが命令を入れ、receiverが実行する。どの状態を受け取ったか分からなければ、各自が忠実に処理しても文章を裏切る。

RFC 1556の歴史は、MIMEがヘブライ語やアラビア語を運べなかった話ではない。MIMEは旅を可能にした。短いRFCは、旅の領収書を読解証明にすり替えなかった。

同じ列は無傷の到着を示す。方式と制御の保存は解釈文脈を示す。名前付きrendererの試験は一つの可視結果を示す。三つが揃って初めて、「正しく届いた」は「byteがここにある」以上の意味を持つ。

出典