[62] '''ToUnicode''' は、[[Unicode]] の[[文字列]]をできるだけ[[正規化]]し、
[[Punycode]] を[[復号]]する[[操作]]です。

* 仕様書

[REFS[
- [22] [CITE@en-us[UTS #46: Unicode IDNA Compatibility Processing]] ([TIME[2010-10-30 01:01:25 +09:00]] 版)
-- [25] <http://www.unicode.org/reports/tr46/#Compatibility_Processing>
-- [44] '''<http://www.unicode.org/reports/tr46/#Processing>'''
-- [95] [CITE@en-us[UTS #46: Unicode IDNA Compatibility Processing]] ([TIME[2010-10-30 01:01:25 +09:00]] 版) <http://unicode.org/reports/tr46/#ToASCII>
-- [17] '''<http://www.unicode.org/reports/tr46/#ToUnicode>'''
-- [23] '''<http://www.unicode.org/reports/tr46/#IDNA2008_Preprocessing>'''
- [76] [CITE@en[URL Standard]] ([TIME[2016-08-25 16:02:43 +09:00]]) <https://url.spec.whatwg.org/#concept-domain-to-unicode>
- [110] [CITE@en[URL Standard]] ([TIME[2016-08-25 16:02:43 +09:00]]) <https://url.spec.whatwg.org/#dom-url-domaintounicode>
]REFS]


* ドメインをUnicodeに

[77] [DFN[[RUBYB[ドメインをUnicodeに]@en[domain to Unicode]]]]する[[演算]]は、
[[ドメイン]][VAR[ドメイン]]を、次のようにします [SRC[>>76]]。

[FIG(steps)[
= [78] ([VAR[結果]]、[VAR[誤り]]) を、 [[UTS #46]] [[ToUnicode]] の結果に設定します。
[FIG(list members middle)[

: [VAR[ドメイン名]] : [VAR[ドメイン]]
: [VAR[[[CheckHyphens]]]] : [[偽]]
: [VAR[[[CheckBidi]]]] : [[真]]
: [VAR[[[CheckJoiners]]]] : [[真]]
: [VAR[[[UseSTD3ASCIIRules]]]] : [[偽]]
: [VAR[[[移行的処理]]]] : [[偽]]

]FIG]
= [79] [VAR[誤り]]が[[真]]の場合、
== [80] [[構文違反]]を報告します。
= [81] [VAR[結果]]を返します。
]FIG]

[82] この[[演算]]は、次の場面で呼び出されます。

[FIG(middle list)[ [123] [[ドメインをUnicodeに]]する場面
- [[URLのレンダリング]]における[[ホスト]]の[[表示]]

[HISTORY[
- [[起源のUnicode直列化]]
- [[ホスト構文解析器]] ([VAR[Unicodeフラグ]]設定時)
]HISTORY]
]FIG]

* UTS #46 の ToUnicode 演算

[19] [[UTS #46]] の [DFN[ToUnicode]] [[演算]]は、
[[入力]]として次のものを受け取ります [SRC[>>17]]。
[FIG(list members middle)[
: [VAR[ドメイン名]] : [[Unicode文字列]]
: [VAR[[[UseSTD3ASCIIRules]]]] : [[boolean]]
: [VAR[[[CheckHyphens]]]] : [[boolean]]
: [VAR[[[CheckBidi]]]] : [[boolean]]
: [VAR[[[CheckJoiners]]]] : [[boolean]]
]FIG]

[38] 次のようにします [SRC[>>17]]。
[FIG(steps)[
= [70] ([VAR[ドメイン名]]、[VAR[誤り]]) を、[[Unicode IDNA互換性処理]]の結果に設定します。
[FIG(list members middle)[
: [VAR[ドメイン名]] : [VAR[ドメイン名]]
: [VAR[[[UseSTD3ASCIIRules]]]] : [VAR[[[UseSTD3ASCIIRules]]]]
: [VAR[[[CheckHyphens]]]] : [VAR[[[CheckHyphens]]]]
: [VAR[[[CheckBidi]]]] : [VAR[[[CheckBidi]]]]
: [VAR[[[CheckJoiners]]]] : [VAR[[[CheckJoiners]]]]
: [VAR[処理オプション]] : [[非移行的処理]]
]FIG]
= [71] ([VAR[ドメイン名]]、[VAR[誤り]]) を返します。
]FIG]

;; [18] [[UTS #46]] の [[ToUnicode]] [[演算]]は、[[ラベル]]ではなく[[ドメイン名]]全体に対して定義されています。

[73] 利用される場面は、 >>72 を参照。

[74] テストデータ:

[REFS[
- [75] [CITE[IdnaTest.txt]] ([TIME[2016-06-21 06:36:28 +09:00]]) <http://www.unicode.org/Public/idna/latest/IdnaTest.txt>
]REFS]

* Unicode IDNA互換性処理

[63] [DFN[Unicode IDNA[RUBYB[互換性処理][Compatibility Processing]]]]は[[ドメイン名]]に含まれる[[文字]]を[[正規化]]し、
[[Punycode]] を[[復号]]します。これは [[ToUnicode]] [[操作]]そのものであると共に、
[[IDNA2008前処理]]として [[IDNA2008]] 本体での処理の前段階として用いたり、
[[ToASCII]] [[操作]]の最初の手順として用いたりします。 [[Unicode]]
に戻すために使うだけでなく、 [[ASCII]] ([[Punycode]]) にしたいときもまずはできるだけ
[[Unicode]] 化して[[正規化]]した状態にするということですね。

[41] [[入力]]は、次のものです [SRC[>>44]]。
[FIG(list members)[
: [VAR[ドメイン名]] : [[Unicode文字列]]
: [VAR[[[UseSTD3ASCIIRules]]]] : [[boolean]]
: [VAR[[[CheckBidi]]]] : [[boolean]]
: [VAR[[[CheckJoiners]]]] : [[boolean]]
: [DFN[[VAR[[[CheckHyphens]]]]]] : [[boolean]]
: [VAR[処理オプション]] : [DFN[[RUBYB[[[移行的処理]]]@en[Transitional Processing]]]]または[DFN[[RUBYB[[[非移行的処理]]]@en[Nontransitional Processing]]]]
: [VAR[Punycode符号化]] : [[boolean]] (既定値は[[偽]])
: [VAR[VerifyDnsLength]] : [[boolean]]
]FIG]

[64] [[移行的処理]]と[[非移行的処理]]の違いは [[IDNA2003]] と [[IDNA2008]]
で [[Aラベル]] ([[ACEラベル]]) への変換結果が変わってしまう4文字の扱いだけ [SRC[>>25]] です。
[[移行的処理]]はこの4文字を [[IDNA2003]] 風に[[写像]]して他の文字に変えたり削除したりしますが、
[[非移行的処理]]ではそのまま残します。

[45] [[出力]]は、 ([[Unicode文字列]], [[boolean]]) の組です。
[[Unicode文字列]]は、変換結果です。 [[boolean]] は、[[誤り]]の有無を表します。
[[誤り]]があっても、出来る限りの変換結果の文字列が返されます。 [SRC[>>44]]

[34] 次のようにします [SRC[>>44]]。
[FIG(steps)[
= [46] [VAR[結果]]を、[[空文字列]]に設定します。
= [42] [VAR[誤り]]を、[[偽]]に設定します。
= [49] [RUBYB[[[写像]]]@en[map]]: [VAR[ドメイン名]]の各[[符号位置]][VAR[符号]]について、
順に、
== [50] [[IDNA写像表]] ([VAR[[[UseSTD3ASCIIRules]]]]) における[VAR[符号]]の[[状態値]]により、
[FIG(switch)[
: [RUBYB[[[禁止]]]@en[disallowed]] : [VAR[誤り]]を、[[真]]に設定します。
: [RUBYB[[[無視]]]@en[ignored]] : [VAR[符号]]を、 [CODE[null]] に設定します。
: [RUBYB[[[写像]]]@en[mapped]] :
[VAR[符号]]を、[[IDNA写像表]] ([VAR[[[UseSTD3ASCIIRules]]]]) 
における[VAR[符号]]の[[写像値]]に設定します。
: [RUBYB[[[偏差]]]@en[deviation]] :
[VAR[処理オプション]]が[[移行的処理]]なら、
[VAR[符号]]を、[[IDNA写像表]] ([VAR[[[UseSTD3ASCIIRules]]]]) 
における[VAR[符号]]の[[写像値]]に設定します。
]FIG]
== [47] [VAR[符号]]が [CODE[null]] でなければ、
=== [43] [VAR[結果]]の末尾に[[符号位置]][VAR[符号]]を追加します。
= [58] [RUBYB[[[正規化]]]@en[normalize]]: 
[VAR[結果]]を、 [VAR[結果]]に [[NFC]] を適用した結果に設定します。
= [59] [RUBYB[[[切断]]]@en[break]]: 
[VAR[ラベル群]]を、[VAR[結果]]を [CODE[.][U+002E]] で分割した結果に設定します。
= [60] [RUBYB[[[変換]]・[[妥当性検証]]]@en[convert/validate]]:
[VAR[ラベル群]]の各項目[VAR[ラベル]]について、順に、
== [61] [VAR[ラベル]]の先頭が [CODE[xn--]] なら、
=== [48] [VAR[結果]]を、[VAR[ラベル]]から先頭4文字を除去したものに 
[[Punycode復号]]を適用した結果に設定します。
=== [28] [VAR[結果]]が[[失敗]]の場合、
==== [39] [VAR[誤り]]を、[[真]]に設定します。
=== [51] それ以外の場合、
==== [29] [VAR[ラベル群]]における[VAR[ラベル]]を、[VAR[結果]]で置き換えます。
以後[VAR[ラベル]]は[VAR[結果]]とします。
==== [30] [VAR[結果]]を、
[VAR[ラベル]]が[[非移行的処理]]、[VAR[[[UseSTD3ASCIIRules]]]]、
[VAR[[[CheckHyphens]]]]、
[VAR[[[CheckBidi]]]]、
[VAR[[[CheckJoiners]]]] についての[[妥当性基準]]に合致するか否かに設定します。
==== [52] [VAR[結果]]が[[偽]]なら、
===== [53] [VAR[誤り]]を、[[真]]に設定します。
== [31] それ以外の場合、
=== [32] [VAR[結果]]を、
[VAR[ラベル]]が[VAR[処理オプション]]、[VAR[[[UseSTD3ASCIIRules]]]]、
[VAR[[[CheckHyphens]]]]、
[VAR[[[CheckBidi]]]]、
[VAR[[[CheckJoiners]]]] についての[[妥当性基準]]に合致するか否かに設定します。
=== [54] [VAR[結果]]が[[偽]]なら、
==== [55] [VAR[誤り]]を、[[真]]に設定します。
== [96] [VAR[Punycode符号化]]が[[真]]の場合 [SRC[>>95]]、
=== [97] [VAR[ラベル]]に[[非ASCII文字]]が含まれるなら、
==== [98] [VAR[符号化ラベル]]を、 [CODE[xn--]] の後に[VAR[ラベル]]に[[Punycode符号化]]を適用した結果を連結したものに設定します。
==== [99] [VAR[ラベル群]]の[VAR[ラベル]]を、[VAR[符号化ラベル]]で置き換えます。
以後[VAR[ラベル]]は[VAR[符号化ラベル]]とします。
== [100] [VAR[VerifyDnsLength]] が[[真]]なら、
=== [101] [VAR[ラベル]]の長さが[[範囲]] [ [N[1]], [N[63]] ] に含まれなければ、
==== [102] [VAR[誤り]]を、[[真]]に設定します。
= [57] [VAR[結果]]を、[VAR[ラベル群]]の各項目を [CODE[.][U+002E]] で連結した結果に設定します。
= [103] [VAR[VerifyDnsLength]] が[[真]]の場合 [SRC[>>95]]、
== [104] [VAR[結果]]の長さ (末尾が [CODE[U+002E]] の場合、それを無視した長さ)
が[[範囲]] [ [N[1]], [N[253]] ] に含まれなければ、
=== [105] [VAR[誤り]]を、[[真]]に設定します。
= [56] ([VAR[結果]]、[VAR[誤り]]) を返します。
]FIG]

[33] [VAR[誤り]]が[[真]]なら[[成功]]、そうでなければ[[失敗]]です。 [SRC[>>44]]

;; [106] [[仕様書]]では、 [VAR[Punycode符号化]]と [VAR[VerifyDnsLength]]
の処理は[[Unicode IDNA互換性処理]]自体ではなく、それを呼び出す [[ToASCII]]
演算の一部として定義されています。

[65] 実装は、[[利用者]]に[[表示]]する時には、更に変更を加えても構いません。
例えば[VAR[誤り]]が[[真]]に設定される原因の部分を [CODE[U+FFFD]]
に置き換えたりすることが[RUBYB[推奨]@en[recommend]]されます。 [SRC[>>44]]

[35] この[[算法]]は[[冪等]]です。 [SRC[>>44]]

[107] 利用される場面は、 >>72 を参照。

-*-*-

[37] 誤りとなる場合の処理は、 [[Chrome]] も [[Firefox]] も、[[仕様書]]とは少しずつ違うようです。
両者も互いに異なります。[[非ASCII文字]]を含む場合、含まない場合、
誤りとなる文字の種別、 [CODE[xn--]] から始まる場合、
[[Aラベル]]を[[復号]]したら不正な場合などでそれぞれ違った結果になります。

[85] [[Chrome]] でも [[Firefox]] でも、入力 (正規化前) の[[ドメイン名]]全体で[[非ASCII文字]]をまったく含まないなら[[妥当性基準]]を検証しないようです。
[TIME[2016-08-28T03:03:52.300Z]]

[89] [[Firefox]] は[[妥当性基準]]のうち [CODE[-]] の検査を行わないようです。
[[Chrome]] は[[ドメイン名]]全体で[[非ASCII文字]]を含む時、
[[ASCII文字]]のみの[[ラベル]]も含め、行うようです。
[TIME[2016-08-28T03:15:33.000Z]]

[91] [[Chrome]] は[[偏差]]となる [CODE[U+200C]] と [CODE[U+200D]]
を[[無視]]としています ([[移行的処理]]の挙動)。
[[Firefox]] は[[妥当]]として扱い ([[非移行的処理]]の挙動)、
[[ContextJ規則]]の検査も行いません。 [TIME[2016-08-28T03:39:10.400Z]]

[90] [[IE]] は、 [[bidi規則]]の検査は
([[IDNA2008]] 相当も [[IDNA2003]] 相当も) 行っていないらしいです。

[92] [[Firefox]] も [[bidi規則]]の検査は行っていないようです。 [TIME[2016-08-28T03:24:19.700Z]]

[93] [[Chrome]] は [[IDNA2003]] 相当の検査は行っていないようですが、
何らかの検査は行っているようにみえます。 [TIME[2016-08-28T06:18:45.100Z]]

[108] [[Chrome]] は[[非ASCII文字]]が含まれるとき、
最後 ([[末尾の点]]後) 以外の[[ラベル]]が空かどうか検査し、
空だとエラーとするようです。
[[非ASCII文字]]が含まれなければエラーにはしません。 [TIME[2016-08-28T14:43:18.500Z]]

[109] [[Chrome]] は[[非ASCII文字]]が含まれる時、
[[ラベル]]の長さの検査も行うようです。 [TIME[2016-09-01T08:24:39.500Z]]

[EG[
[94] [CODE(JS)[new URL ("http://\u0640a")]] は [[Chrome]] でエラーになります。
[[Firefox]] ではエラーになりません。 [TIME[2016-08-28T06:20:14.100Z]]
]EG]

[HISTORY[
[83] [[IDNA2003]] 時代は、[[写像]]などの処理は [[Nameprep]] によって規定されていました。
(ただし [[IDNA2003]] の[[仕様書]]は[[ラベル]]に対する演算としているのに対し、
現実には[[ドメイン]]に対する演算として実装されていて、その点は当時からすでに現在の
[[UTS #46]] と同じでした。)

[84] [[Nameprep]] では [[NFKC]] を使っていましたが、 [[UTS #46]] では [[NFC]]
を使っています。[[互換分解]]は [[Nameprep]] の他の処理と共に[[写像]]に組み込まれています。

]HISTORY]

** 移行的処理と非移行的処理の選択

[66] 移行期間中の [[DNS lookup]] では[[移行的処理]]を、表示を含むそれ以外の場面では[[非移行的処理]]を使うべきです。
[SRC[>>25 2.1]]
両者の違いは[[偏差]]に分類される4文字だけであり、 [[lookup]] では[[移行的処理]]を使っていたとしても、
表示においては[[非移行的処理]]が[[利用者]]の入力により近い形になるので好ましいです。

** レジストリーにおける対応

[67] [[レジストリー]]にあっては次のいずれかの対応を行うことが強く推奨されています
[RSC[>>25 2.2]]。

- [[Bundling]]: [[移行的処理]]と[[非移行的処理]]の結果が異なるなら、両方が登録される場合には[[登録者]]が同じでなければならない
- [[Blocking]]: [[移行的処理]]と[[非移行的処理]]の結果が異なるなら、両方が登録されることを認めない、あるいはそもそも[[偏差]]の4文字を認めない

** 例

[40] <http://www.unicode.org/reports/tr46/#Table_Example_Processing> にこの[[算法]]の適用例がいくつも示されています。

** メモ

[36] [[利用者]]に[[ドメイン名]]を提示する時には更に変更を加えても構いません。
禁止されている[[文字]]を [CODE(char)[[[U+FFFD]]]] に置き換えたり、
[[妥当性検証]]で失敗した[[ラベル]]を [CODE(char)[[[U+FFFD]]]] その他の表示により[[利用者]]に示したりするのがよいとされています。 [SRC[>>44]]

* 文脈

[72] [[Unicode IDNA互換性処理]]とそれを使った [[ToUnicode]], [[ToASCII]]
は、次の場面で呼び出されます。

[FIG(table col)[
:x3: [[演算]]
:x2: [[演算]]
:x1: [[演算]]
:std3: [VAR[[[UseSTD3ASCIIRules]]]] 
:bidi: [VAR[[[CheckBidi]]]]
:joiners: [VAR[[[CheckJoiners]]]]
:hyphens: [VAR[[[CheckHyphens]]]]
:pr: [VAR[処理オプション]]
:pu: [VAR[Punycode符号化]]
:l: [VAR[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: [VAR[厳密にする]]
:bidi: [[真]]
:joiners: [[真]]
:hyphens: [[偽]]
:pr: [[非移行的処理]]
:pu: [[真]]
:l: [VAR[厳密にする]]

: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: [[真]]

]FIG]

* 関連

[14] 逆の操作として、 [[ToASCII]] [[演算]]があります。

* 歴史

** IDNA2003 の ToUnicode 演算

[1] [[IDNA2003]] の [DFN@en[[CODE@en[ToUnicode]]]] [[演算]]は、
[[国際化ラベル]]を[[ACEラベル]]でない[[国際化ラベル]]に変換します。
大まかに言うと [[Punycode]] を[[復号]]して人間可読な[[文字列]]に戻す操作です。

[REFS[
- [26] [[IDNA2003]]
-- [2] [CITE@en[RFC 3490 - Internationalizing Domain Names in Applications (IDNA)]] 
<https://tools.ietf.org/html/rfc3490#section-4.2>
]REFS]

[86] 入力:
[FIG(list members)[
- [3] [[国際化ラベル]]、すなわち [[Unicode]] [[符号位置]]の列。 [SRC@en[RFC 3490 4.2]]
- [9] [[フラグ]] [CODE@en[[[AllowUnassigned]]]]。 [SRC@en[RFC 3490 4.2]]
- [10] [[フラグ]] [CODE@en[[[UseSTD3ASCIIRules]]]]。 [SRC@en[RFC 3490 4.2]]
]FIG]

[11] [[ToASCII]] を内部的に呼び出すので、 >>10 が入力となっています。直接は使っていません。

[87] 出力:
[FIG(list members)[
- [4] [[国際化ラベル]]、すなわち [[Unicode]] [[符号位置]]の列。 [SRC@en[RFC 3490 4.2]]
-- [12] [[入力]]が [[ACE名札]]なら、
[[等価]]で[[ACE名札]]では''ない''[[国際化名札]]。
-- [13] そうでなければ、元のままの[[国際化名札]]。
]FIG]

[5] [CODE@en[[[ToUnicode]]]] は[[失敗]]しません。
>>8 の[[算法]]が[[失敗]]した場合、
[[入力]]をそのまま[[出力]]とします。
[SRC@en[RFC 3490 4.2]]

[8]
[FIG(steps)[
= すべての[[符号位置]]が [[ASCII]] の範囲
([CODE(char)[[[U+0000]]]]〜[CODE(char)[[[U+007F]]]])
に収まっていれば、 3 に進みます。
= [[Nameprep]] を適用します
([[旗]] [CODE@en[[[AllowUnassigned]]]] を使用します)。
[[誤り]]があれば[[失敗]]とします。
= [[ACE接頭辞]]ではじまることを確認し、
[[符号位置]]の列の複製を作ります。
= [[ACE接頭辞]]を削除します。
= [[Punycode]] を[[復号]]します。
[[誤り]]があれば[[失敗]]とします。
結果の列の複製を作ります。
= [CODE@en[[[ToASCII]]]] を適用します。
= 6 の結果が 3 で作成した複製と[[一致]]することを確認します。
ここで、[[一致]]するかは [[ASCII]]
の[[大文字]]・[[小文字]]を区別しない[[比較]]によります。
= 5 で作成した複製を出力とします。
]FIG]

[15] 確認して違っていたらどうするのでしょう。[[失敗]]とすることを想定しているように見えますが、
明記されていません。

[16] 失敗した場合、 >>5 によりもとの入力が [[ToUnicode]] の結果となります。

[7]
[[出力]]が[[入力]]より[[符号位置]]が増えることはありません。
[SRC@en[RFC 3490 4.2]]

[27] [[IDNA2003]] [[ToUnicode]] は次の場面で使われます。
[FIG(short list)[
- [CODE[[[dNSName]]]]
- [CODE[[[SRVName]]]]
]FIG]

** UTS #46

[88] [[IDNA2003]] では[[ラベル]]に対して、[[UTS #46]] では[[ドメイン名]]に対して
[[ToUnicode]] [[操作]]が定義されています。また、 [[UTS #46]] では
[[ToUnicode]] と [[ToASCII]] の共通の内部操作'''[[Unicode IDNA互換性処理]]'''も定義されています。

** IDNA2008 前処理

[20] [[UTS #46]] の[DFN[[RUBYB[[[IDNA2008前処理]]]@en[Preprocessing for IDNA2008]]]]は、
[WEAK[(完全な [[Unicode IDNA互換性処理]]を行うのとは違って)]]
[[IDNA2008]] の規定する処理に対する[[前処理]]として使うことができる[[算法]]であり、
その[[適合性]]の[[クラス]]です。これは移行処理が特に必要がない場面で利用できます
[SRC[>>25]]。

[21] [[IDNA2008前処理]]とは、[[入力]]となる[[文字列]]に [[ToUnicode]] [[演算]]
(>>19) を適用することと定義されています [SRC[>>23]]。

;; [24] [[IDNA2008前処理]]を適用すると[[大文字]]から[[小文字]]への変換など
[[IDNA2003]]では行われていた処理の一部がなされるようになります。
これだけでは [[IDNA2008]] で認められていない[[文字]]が一部素通しされてしまいますが、
「前」処理であるので問題にはなりません [SRC[>>23]]。

** IDNA2008 問題

[FIG(quote)[
[FIGCAPTION[
[6] [CITE@en[479520 – (IDNA2008) Implement IDNA2008 and Unicode UTS #46]]
([TIME[2015-03-24 19:03:59 +09:00]] 版)
<https://bugzilla.mozilla.org/show_bug.cgi?id=479520#c100>
]FIGCAPTION]

> 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.

]FIG]


[68] [CITE@en[Cleanup definitions of domainToASCII() and domainToUnicode(). Give up… · whatwg/url@d18639f]]
([TIME[2015-08-18 12:14:04 +09:00]] 版)
<https://github.com/whatwg/url/commit/d18639f13cb710938f2251a8f0e40b637aa82823>

[69] [CITE@en[Add a section on rendering URLs with some advice around bidirectional… · whatwg/url@d1152b9]]
([TIME[2015-08-27 11:53:32 +09:00]] 版)
<https://github.com/whatwg/url/commit/d1152b94a16ae91e1f72d128fd5ef589635f0e7c>

** [CODE(DOMi)@en[URL]] インターフェイス [CODE(DOMm)@en[domainToUnicode]] 静的メソッド

[111] [CODE(DOMi)@en[URL]] [[インターフェイス]]の 
[DFN[[CODE(DOMm)@en[domainToUnicode]]]] [[静的メソッド]]は、
次のようにしなければ[MUST[なりません]] [SRC[>>110]]。
[FIG(steps)[
= [112] [VAR[ドメイン]]を、必須の第1引数を [CODE(DOMi)@en[USVString]] として解釈した結果に設定します。
= [113] [VAR[Unicodeドメイン]]を、[VAR[ドメイン]]に[[ホスト構文解析器]]を
[VAR[Unicodeフラグ]]付きで適用した結果に設定します。
= [114] [VAR[Unicodeドメイン]]が[[ドメイン]]なら、
== [115] [VAR[Unicodeドメイン]]を返します。
= [116] それ以外なら、
== [117] [[空文字列]]を返します。
]FIG]

[118] [[ドメインをUnicodeに]]操作を直接呼び出さずに[[ホスト構文解析器]]を挟んでいますから、
[[パーセント符号化]]の処理、[[IPアドレス]]かどうかの判定、
不適切な[[ASCII文字]]の検査が追加で行われます。

[119] [CODE(DOMi)@en[domainToASCII]] [[静的メソッド]]を実行してから[[ドメインをUnicodeに]]を実行するのと等価です。

[120] [CITE@en[Remove URL.domainToASCII and domainToUnicode]]
([[annevk]]著, [TIME[2016-10-19 21:04:17 +09:00]])
<https://github.com/whatwg/url/commit/2bd0f59b98024921ab90e628b7a526cca5abcb5f>

[121] [CITE@en[Use Nontransitional_Processing for IDNA ToASCII]]
([[annevk]]著, [TIME[2017-02-20 18:51:49 +09:00]])
<https://github.com/whatwg/url/commit/f4d84a52e67b154b2d11e04889fe0a35a029c833>

[122] [CITE@en[IDNA: use proposed UTS46 flags to avoid breaking YouTube]]
([[annevk]]著, [TIME[2017-06-02 06:24:01 +09:00]])
<https://github.com/whatwg/url/commit/dc9d83106cada9af507bf37dee3973de97b020fd>

[125] [CITE@en[IDNA / UTS #46 "should" requirements (Bidi and Joiners) · Issue #110 · whatwg/url]]
([TIME[2017-09-03 21:20:31 +09:00]])
<https://github.com/whatwg/url/issues/110>

[126] [CITE@en[IDNA: realign once UTS46 revision 18 is final · Issue #313 · whatwg/url]]
([TIME[2017-09-03 21:23:48 +09:00]])
<https://github.com/whatwg/url/issues/313>

[127] [CITE@en[Address several IDNA issues by annevk · Pull Request #309 · whatwg/url]]
([TIME[2017-09-03 21:24:25 +09:00]])
<https://github.com/whatwg/url/pull/309>

[128] [CITE@en[IDNA · Issue #53 · whatwg/url]]
([TIME[2017-09-03 21:27:04 +09:00]])
<https://github.com/whatwg/url/issues/53>

[129] [CITE@en[IDNA: UTS46 revision 19 is part of Unicode 10]]
([[annevk]]著, [TIME[2017-06-23 02:33:33 +09:00]])
<https://github.com/whatwg/url/commit/b128ba9111c68ad767b472d77d0ada9ef85366ef>

[130] [CITE@en[IDNA: UTS46 revision 19 is part of Unicode 10 by annevk · Pull Request #325 · whatwg/url]]
([TIME[2017-09-03 21:31:43 +09:00]])
<https://github.com/whatwg/url/pull/325>

[124] [CITE@en[Continue to use Nontransitional processing for IDNA]]
([[TRowbotham]]著, [TIME[2018-07-23 21:38:43 +09:00]])
<https://github.com/whatwg/url/commit/6800342832fdf99caa265d0106cf984123716d9d>

[131] [CITE@en[Preserve use of Nontransitional processing for IDNA by TRowbotham · Pull Request #404 · whatwg/url]]
([TIME[2018-07-26 22:30:48 +09:00]])
<https://github.com/whatwg/url/pull/404>

[132] [CITE@en[Restructure URL rendering section and add additional guidance]]
([[estark37]]著, [TIME[2019-04-04 23:49:46 +09:00]])
<https://github.com/whatwg/url/commit/8809598ddfd1d935432c8a0cad53f13d70e24bc6>