Unicode IDNA Compatibility Processing

ToUnicode 演算

[62] ToUnicode は、Unicode文字列をできるだけ正規化し、 Punycode復号する操作です。

仕様書

ドメインをUnicodeに

[77] ドメインをUnicodeに (domain to Unicode) する演算は、 ドメインドメインを、次のようにします >>76

  1. [78] (結果誤り) を、 UTS #46 ToUnicode の結果に設定します。
    ドメイン名
    ドメイン
    CheckHyphens
    CheckBidi
    CheckJoiners
    UseSTD3ASCIIRules
    移行的処理
  2. [79] 誤りの場合、
    1. [80] 構文違反を報告します。
  3. [81] 結果を返します。

[82] この演算は、次の場面で呼び出されます。

[123] ドメインをUnicodeにする場面

UTS #46 の ToUnicode 演算

[19] UTS #46ToUnicode 演算は、 入力として次のものを受け取ります >>17

ドメイン名
Unicode文字列
UseSTD3ASCIIRules
boolean
CheckHyphens
boolean
CheckBidi
boolean
CheckJoiners
boolean

[38] 次のようにします >>17

  1. [70] (ドメイン名誤り) を、Unicode IDNA互換性処理の結果に設定します。
    ドメイン名
    ドメイン名
    UseSTD3ASCIIRules
    UseSTD3ASCIIRules
    CheckHyphens
    CheckHyphens
    CheckBidi
    CheckBidi
    CheckJoiners
    CheckJoiners
    処理オプション
    非移行的処理
  2. [71] (ドメイン名誤り) を返します。

[18] UTS #46ToUnicode 演算は、ラベルではなくドメイン名全体に対して定義されています。

[73] 利用される場面は、 >>72 を参照。

[74] テストデータ:

Unicode IDNA互換性処理

[63] Unicode IDNA互換性処理 (Compatibility Processing) ドメイン名に含まれる文字正規化し、 Punycode復号します。これは ToUnicode 操作そのものであると共に、 IDNA2008前処理として IDNA2008 本体での処理の前段階として用いたり、 ToASCII 操作の最初の手順として用いたりします。 Unicode に戻すために使うだけでなく、 ASCII (Punycode) にしたいときもまずはできるだけ Unicode 化して正規化した状態にするということですね。

[41] 入力は、次のものです >>44

ドメイン名
Unicode文字列
UseSTD3ASCIIRules
boolean
CheckBidi
boolean
CheckJoiners
boolean
CheckHyphens
boolean
処理オプション
移行的処理 (Transitional Processing) または非移行的処理 (Nontransitional Processing)
Punycode符号化
boolean (既定値は)
VerifyDnsLength
boolean

[64] 移行的処理非移行的処理の違いは IDNA2003IDNA2008Aラベル (ACEラベル) への変換結果が変わってしまう4文字の扱いだけ >>25 です。 移行的処理はこの4文字を IDNA2003 風に写像して他の文字に変えたり削除したりしますが、 非移行的処理ではそのまま残します。

[45] 出力は、 (Unicode文字列, boolean) の組です。 Unicode文字列は、変換結果です。 boolean は、誤りの有無を表します。 誤りがあっても、出来る限りの変換結果の文字列が返されます。 >>44

[34] 次のようにします >>44

  1. [46] 結果を、空文字列に設定します。
  2. [42] 誤りを、に設定します。
  3. [49] 写像 (map) : ドメイン名の各符号位置符号について、 順に、
    1. [50] IDNA写像表 (UseSTD3ASCIIRules) における符号状態値により、
      禁止 (disallowed)
      誤りを、に設定します。
      無視 (ignored)
      符号を、 null に設定します。
      写像 (mapped)
      符号を、IDNA写像表 (UseSTD3ASCIIRules) における符号写像値に設定します。
      偏差 (deviation)
      処理オプション移行的処理なら、 符号を、IDNA写像表 (UseSTD3ASCIIRules) における符号写像値に設定します。
    2. [47] 符号null でなければ、
      1. [43] 結果の末尾に符号位置符号を追加します。
  4. [58] 正規化 (normalize) : 結果を、 結果NFC を適用した結果に設定します。
  5. [59] 切断 (break) : ラベル群を、結果. で分割した結果に設定します。
  6. [60] 変換妥当性検証 (convert/validate) : ラベル群の各項目ラベルについて、順に、
    1. [61] ラベルの先頭が xn-- なら、
      1. [48] 結果を、ラベルから先頭4文字を除去したものに Punycode復号を適用した結果に設定します。
      2. [28] 結果失敗の場合、
        1. [39] 誤りを、に設定します。
      3. [51] それ以外の場合、
        1. [29] ラベル群におけるラベルを、結果で置き換えます。 以後ラベル結果とします。
        2. [30] 結果を、 ラベル非移行的処理UseSTD3ASCIIRulesCheckHyphensCheckBidiCheckJoiners についての妥当性基準に合致するか否かに設定します。
        3. [52] 結果なら、
          1. [53] 誤りを、に設定します。
    2. [31] それ以外の場合、
      1. [32] 結果を、 ラベル処理オプションUseSTD3ASCIIRulesCheckHyphensCheckBidiCheckJoiners についての妥当性基準に合致するか否かに設定します。
      2. [54] 結果なら、
        1. [55] 誤りを、に設定します。
    3. [96] Punycode符号化の場合 >>95
      1. [97] ラベル非ASCII文字が含まれるなら、
        1. [98] 符号化ラベルを、 xn-- の後にラベルPunycode符号化を適用した結果を連結したものに設定します。
        2. [99] ラベル群ラベルを、符号化ラベルで置き換えます。 以後ラベル符号化ラベルとします。
    4. [100] VerifyDnsLengthなら、
      1. [101] ラベルの長さが範囲 [ 1, 63 ] に含まれなければ、
        1. [102] 誤りを、に設定します。
  7. [57] 結果を、ラベル群の各項目を . で連結した結果に設定します。
  8. [103] VerifyDnsLengthの場合 >>95
    1. [104] 結果の長さ (末尾が U+002E の場合、それを無視した長さ) が範囲 [ 1, 253 ] に含まれなければ、
      1. [105] 誤りを、に設定します。
  9. [56] (結果誤り) を返します。

[33] 誤りなら成功、そうでなければ失敗です。 >>44

[106] 仕様書では、 Punycode符号化VerifyDnsLength の処理はUnicode IDNA互換性処理自体ではなく、それを呼び出す ToASCII 演算の一部として定義されています。

[65] 実装は、利用者表示する時には、更に変更を加えても構いません。 例えば誤りに設定される原因の部分を U+FFFD に置き換えたりすることが推奨 (recommend) されます。 >>44

[35] この算法冪等です。 >>44

[107] 利用される場面は、 >>72 を参照。


[37] 誤りとなる場合の処理は、 ChromeFirefox も、仕様書とは少しずつ違うようです。 両者も互いに異なります。非ASCII文字を含む場合、含まない場合、 誤りとなる文字の種別、 xn-- から始まる場合、 Aラベル復号したら不正な場合などでそれぞれ違った結果になります。

[85] Chrome でも Firefox でも、入力 (正規化前) のドメイン名全体で非ASCII文字をまったく含まないなら妥当性基準を検証しないようです。

[89] Firefox妥当性基準のうち - の検査を行わないようです。 Chromeドメイン名全体で非ASCII文字を含む時、 ASCII文字のみのラベルも含め、行うようです。

[91] Chrome偏差となる U+200CU+200D無視としています (移行的処理の挙動)。 Firefox妥当として扱い (非移行的処理の挙動)、 ContextJ規則の検査も行いません。

[90] IE は、 bidi規則の検査は (IDNA2008 相当も IDNA2003 相当も) 行っていないらしいです。

[92] Firefoxbidi規則の検査は行っていないようです。

[93] ChromeIDNA2003 相当の検査は行っていないようですが、 何らかの検査は行っているようにみえます。

[108] Chrome非ASCII文字が含まれるとき、 最後 (末尾の点後) 以外のラベルが空かどうか検査し、 空だとエラーとするようです。 非ASCII文字が含まれなければエラーにはしません。

[109] Chrome非ASCII文字が含まれる時、 ラベルの長さの検査も行うようです。

[94] new URL ("http://\u0640a")Chrome でエラーになります。 Firefox ではエラーになりません。

[83] IDNA2003 時代は、写像などの処理は Nameprep によって規定されていました。 (ただし IDNA2003仕様書ラベルに対する演算としているのに対し、 現実にはドメインに対する演算として実装されていて、その点は当時からすでに現在の UTS #46 と同じでした。)

[84] Nameprep では NFKC を使っていましたが、 UTS #46 では NFC を使っています。互換分解Nameprep の他の処理と共に写像に組み込まれています。

移行的処理と非移行的処理の選択

[66] 移行期間中の DNS lookup では移行的処理を、表示を含むそれ以外の場面では非移行的処理を使うべきです。 >>25 2.1 両者の違いは偏差に分類される4文字だけであり、 lookup では移行的処理を使っていたとしても、 表示においては非移行的処理利用者の入力により近い形になるので好ましいです。

レジストリーにおける対応

[67] レジストリーにあっては次のいずれかの対応を行うことが強く推奨されています >>25 2.2。

[40] http://www.unicode.org/reports/tr46/#Table_Example_Processing にこの算法の適用例がいくつも示されています。

メモ

[36] 利用者ドメイン名を提示する時には更に変更を加えても構いません。 禁止されている文字U+FFFD に置き換えたり、 妥当性検証で失敗したラベルU+FFFD その他の表示により利用者に示したりするのがよいとされています。 >>44

文脈

[72] Unicode IDNA互換性処理とそれを使った ToUnicode, ToASCII は、次の場面で呼び出されます。

x3
演算
x2
演算
x1
演算
std3
UseSTD3ASCIIRules
bidi
CheckBidi
joiners
CheckJoiners
hyphens
CheckHyphens
pr
処理オプション
pu
Punycode符号化
l
VerifyDnsLength
x1
UTS #46 ToUnicode
std3
引数
bidi
引数
joiners
引数
hyphens
引数
pr
非移行的処理
pu
l
x2
IDNA2008前処理
x1
UTS #46 ToUnicode
x2
ドメインをUnicodeに
x1
UTS #46 ToUnicode
std3
bidi
joiners
hyphens
pr
非移行的処理
pu
l
x2
妥当なドメイン
x1
UTS #46 ToUnicode
std3
bidi
joiners
hyphens
pr
非移行的処理
pu
l

x1
UTS #46 ToASCII
std3
引数
bidi
引数
joiners
引数
hyphens
引数
pr
引数
pu
l
引数
x2
ドメインをASCIIに
x1
UTS #46 ToASCII
std3
厳密にする
bidi
joiners
hyphens
pr
非移行的処理
pu
l
厳密にする
x3
ホスト構文解析器
x2
ドメインをASCIIに
x1
UTS #46 ToASCII
std3
bidi
joiners
hyphens
pr
非移行的処理
pu
l
x3
妥当なドメイン
x2
ドメインをASCIIに
x1
UTS #46 ToASCII
std3
bidi
joiners
hyphens
pr
非移行的処理
pu
l

関連

[14] 逆の操作として、 ToASCII 演算があります。

歴史

IDNA2003 の ToUnicode 演算

[1] IDNA2003ToUnicode 演算は、 国際化ラベルACEラベルでない国際化ラベルに変換します。 大まかに言うと Punycode復号して人間可読な文字列に戻す操作です。

[86] 入力:

[11] ToASCII を内部的に呼び出すので、 >>10 が入力となっています。直接は使っていません。

[87] 出力:

[5] ToUnicode失敗しません。 >>8算法失敗した場合、 入力をそのまま出力とします。 RFC 3490 4.2

[8]

  1. すべての符号位置ASCII の範囲 (U+0000U+007F) に収まっていれば、 3 に進みます。
  2. Nameprep を適用します ( AllowUnassigned を使用します)。 誤りがあれば失敗とします。
  3. ACE接頭辞ではじまることを確認し、 符号位置の列の複製を作ります。
  4. ACE接頭辞を削除します。
  5. Punycode復号します。 誤りがあれば失敗とします。 結果の列の複製を作ります。
  6. ToASCII を適用します。
  7. 6 の結果が 3 で作成した複製と一致することを確認します。 ここで、一致するかは ASCII大文字小文字を区別しない比較によります。
  8. 5 で作成した複製を出力とします。

[15] 確認して違っていたらどうするのでしょう。失敗とすることを想定しているように見えますが、 明記されていません。

[16] 失敗した場合、 >>5 によりもとの入力が ToUnicode の結果となります。

[7] 出力入力より符号位置が増えることはありません。 RFC 3490 4.2

[27] IDNA2003 ToUnicode は次の場面で使われます。

UTS #46

[88] IDNA2003 ではラベルに対して、UTS #46 ではドメイン名に対して ToUnicode 操作が定義されています。また、 UTS #46 では ToUnicodeToASCII の共通の内部操作Unicode IDNA互換性処理も定義されています。

IDNA2008 前処理

[20] UTS #46IDNA2008前処理 (Preprocessing for IDNA2008) は、 (完全な Unicode IDNA互換性処理を行うのとは違って) IDNA2008 の規定する処理に対する前処理として使うことができる算法であり、 その適合性クラスです。これは移行処理が特に必要がない場面で利用できます >>25

[21] IDNA2008前処理とは、入力となる文字列ToUnicode 演算 (>>19) を適用することと定義されています >>23

[24] IDNA2008前処理を適用すると大文字から小文字への変換など IDNA2003では行われていた処理の一部がなされるようになります。 これだけでは IDNA2008 で認められていない文字が一部素通しされてしまいますが、 「前」処理であるので問題にはなりません >>23

IDNA2008 問題

[6] 479520 – (IDNA2008) Implement IDNA2008 and Unicode UTS #46 ( 版) https://bugzilla.mozilla.org/show_bug.cgi?id=479520#c100

my understanding is that Microsoft and Google do not want to switch away from Transitional until at least some solution is found to the attacks mentioned in this bug.

[68] Cleanup definitions of domainToASCII() and domainToUnicode(). Give up… · whatwg/url@d18639f ( 版) https://github.com/whatwg/url/commit/d18639f13cb710938f2251a8f0e40b637aa82823

[69] Add a section on rendering URLs with some advice around bidirectional… · whatwg/url@d1152b9 ( 版) https://github.com/whatwg/url/commit/d1152b94a16ae91e1f72d128fd5ef589635f0e7c

URL インターフェイス domainToUnicode 静的メソッド

[111] URL インターフェイスdomainToUnicode 静的メソッドは、 次のようにしなければなりません >>110

  1. [112] ドメインを、必須の第1引数を USVString として解釈した結果に設定します。
  2. [113] Unicodeドメインを、ドメインホスト構文解析器Unicodeフラグ付きで適用した結果に設定します。
  3. [114] Unicodeドメインドメインなら、
    1. [115] Unicodeドメインを返します。
  4. [116] それ以外なら、
    1. [117] 空文字列を返します。

[118] ドメインをUnicodeに操作を直接呼び出さずにホスト構文解析器を挟んでいますから、 パーセント符号化の処理、IPアドレスかどうかの判定、 不適切なASCII文字の検査が追加で行われます。

[119] domainToASCII 静的メソッドを実行してからドメインをUnicodeにを実行するのと等価です。

[120] Remove URL.domainToASCII and domainToUnicode (annevk著, ) https://github.com/whatwg/url/commit/2bd0f59b98024921ab90e628b7a526cca5abcb5f

[121] Use Nontransitional_Processing for IDNA ToASCII (annevk著, ) https://github.com/whatwg/url/commit/f4d84a52e67b154b2d11e04889fe0a35a029c833

[122] IDNA: use proposed UTS46 flags to avoid breaking YouTube (annevk著, ) https://github.com/whatwg/url/commit/dc9d83106cada9af507bf37dee3973de97b020fd

[125] IDNA / UTS #46 "should" requirements (Bidi and Joiners) · Issue #110 · whatwg/url () https://github.com/whatwg/url/issues/110

[126] IDNA: realign once UTS46 revision 18 is final · Issue #313 · whatwg/url () https://github.com/whatwg/url/issues/313

[127] Address several IDNA issues by annevk · Pull Request #309 · whatwg/url () https://github.com/whatwg/url/pull/309

[128] IDNA · Issue #53 · whatwg/url () https://github.com/whatwg/url/issues/53

[129] IDNA: UTS46 revision 19 is part of Unicode 10 (annevk著, ) https://github.com/whatwg/url/commit/b128ba9111c68ad767b472d77d0ada9ef85366ef

[130] IDNA: UTS46 revision 19 is part of Unicode 10 by annevk · Pull Request #325 · whatwg/url () https://github.com/whatwg/url/pull/325

[124] Continue to use Nontransitional processing for IDNA (TRowbotham著, ) https://github.com/whatwg/url/commit/6800342832fdf99caa265d0106cf984123716d9d

[131] Preserve use of Nontransitional processing for IDNA by TRowbotham · Pull Request #404 · whatwg/url () https://github.com/whatwg/url/pull/404

[132] Restructure URL rendering section and add additional guidance (estark37著, ) https://github.com/whatwg/url/commit/8809598ddfd1d935432c8a0cad53f13d70e24bc6