noncharacters

非文字 (Unicode)

[1] Unicode のいくつかの符号位置は、 非文字 (ひもじ) (noncharacters) とされています。

仕様書

意味

[72] 非文字 (ひもじ) (Noncharacter) は、 符号点型の1つです。 >>71 D10a

[13] 非文字は、 内部用に恒久的に予約されている符号点です。 >>71 D14, >>38 字義通り単に「文字ではない」という意味ではなく非文字という1つの独立した分類であって、 noncharacter と1語で表記します。 文字ではありませんが、 Unicode符号位置ではあります。 抽象文字は割当済ではありませんが、 未割当符号点とは違う割当済符号点とされます。

[20] Unicode符号位置には、 他にもサロゲート未割当符号位置のような文字でないものがありますが、 それらは非文字ではありませんUnicode文字ではない絵や記号やその他のオブジェクトも非文字ではありません。

[44] アプリケーションは、 内部用に自由に非文字符号点を使えます。 >>38, >>75 C2 ただ非文字のうち U+FFFE は想定用途が設定されています (>>7)。 U+FFFF, U+10FFFF にも利用例が示されています (>>14)。

[15] 非文字アプリケーションの内部用途以外の情報交換で出現したとしても、 The Unicode Standard はそれに対して標準的な解釈は無い (意味を定義しない) としています。 >>38

[49] 非文字は、 アプリケーション内部用の私用文字的なものです。 真の私用文字は (私的な同意のもと) 開放型情報交換での利用が想定される割り当てられた文字であるのに対し、 非文字アプリケーション外部での解釈を持たない恒久的に予約された未割当符号位置である点が違います。 >>38

[11]

C7
When a process purports not to modify the interpretation of a valid coded character sequence, it shall make no change to that coded character sequence other than the possible replacement of character sequences by their canonical-equivalent sequences or the deletion of noncharacter code points.
  • (中略)
  • If a noncharacter that does not have a specific internal use is unexpectedly encountered in processing, an implementation may signal an error or delete or ignore the noncharacter. If these options are not taken, the noncharacter should be treated as an unassigned code point. For example, an API that returned a character property value for a noncharacter would return the same value as the default value for an unassigned code point.
  • (後略)

[12]

D15 Reserved code point
Any code point of the Unicode Standard that is reserved for future assignment. Also known as an unassigned code point.
  • Surrogate code points and noncharacters are considered assigned code points, but not assigned characters.
  • (後略)

[9]

These codes are intended for process-internal uses, but are not permitted for interchange.

符号点

[32] 非文字符号位置は、66個あります。 >>38, >>71 D14

U+FDD0〜U+FDEF

[42] U+FDD0 - U+FDEF の32個の符号位置は、 非文字です。 >>38

[43] 歴史的理由により Arabic Presentation Forms-A ブロックに含まれますが、 関係はありません。 アラビア文字用でも右横書き用でもなく、 他の非文字と用途は違いません。 >>38

[2] 複数の仕様書が、 「U+FDD0〜U+FDEF」 の32個の符号位置ではなく、誤って 「U+FDD0〜U+FDDF」 の16個の符号位置としていました。

[8] Unicode 5.1 の Code Chart PDF にすら、

This block also contains 32 noncharacters in the range FDD0‐FDDF.

と間違った記述が含まれていました。

[55] Unicode 4.0PDF http://www.unicode.org/charts/PDF/Unicode-4.0/U40-FB50.pdf には該当部分の記述がそもそもなかったみたいです。

[5] XML は、 XML 1.0 4e E02、 XML 1.1 2e E02 でこの誤りを修正しました >>56, >>57。 この修正は適合性には影響しませんでした。 (XML 1.1名前開始文字の定義は非文字を除外する形になっていましたが、 その除外領域は間違っていませんでした。) XMLにおける文字

[3] HTML5 は、 の改訂 r2708 でこの誤りを修正しました >>48HTML構文解析器の挙動 (文字参照) と HTML文書適合性に影響しました。

[78] Solstitium は、 bidi の制御の文字と同じように縦書き用の指示を記述するために非文字を使っています。 書字方向

U+FFFE

[7] U+FFFE は、 U+FEFF と対になる符号位置です。 U+FEFF BOMUTF-16 で表した時、 大エンディアンなら 0xFEFF小エンディアンなら 0xFFFE となります。 BOM 従って文字列の先頭でエンディアンの判定に利用でき、 U+FFFE として出現したならエンディアンが間違っていることがわかります。 故にアプリケーションは、 U+FFFEエンディアンが逆であることを示す内部信号として予約するべき (should) です >>38

[58] 実用を考えると、 この符号位置を何らかのアプリケーション依存の用途に使うと、 逆のエンディアンBOM と解釈されてしまう可能性があるわけですから、 とても安全とはいえません。 BOM 判定コードの条件分岐の記述以外の一切の用途に使うべきではなさそうです。

U+FFFF

[14] U+FFFF は、 16ビット符号単位の最大値 0xFFFF です。 また U+10FFFF は、 Unicode符号位置の最大値 0x10FFFF です。 これを使って、 例えばリストの終端を示したり、 他のどの文字よりも大きな値として使ったりできます。 >>38

特性

[51] 私用文字特性値UCD に示されたままではなく、 割り当てた文字に合わせて変更することを認めています。 私用文字 一方非文字に対しては同様の規定はありません。

[52] アプリケーションは任意の目的で内部的に非文字を取り扱うことを認められているのですから、 特性値を任意の値に読み替えたとしても、 ただちに仕様違反とはならないはずです。 非文字はあくまでアプリケーション内でのみ使うことが想定されたものですから、 どう処理しようとも相互運用性には影響しないはずです。

[53] 逆にそれが相互運用性に悪影響を及ぼす形で観測され得るとしたら、 それは非文字の用法として不適切であるとも考えられます。

[77] 非文字General CategoryCn です >>10Cn には他に未割当符号点も含まれます。 Cn

安定性

[73] 非文字符号点は、 恒久的に非文字として予約されています。 >>71 D14

[45] The Unicode Standard は、 非文字の意味を定めていません。 The Unicode Standard は、 自身が非文字情報交換可能な意味を割り当てることを、 恒久的に禁止しています。 >>38

[74] つまり既に非文字として定義された符号点が、 非文字でなくなることはありません。

[50] 現在の非文字は、過去の The Unicode Standard で段階的に追加されたものでした。 ここ数年新規追加はされておらず、 近い将来に追加されそうな見込みもありませんが、 今後どうなるかは不明です。

文脈

[59] Unicode文字列は、 一般的には Unicode符号位置の列で、 非文字が含まれる可能性もあります。

[46] The Unicode Standard は、 Unicode文字列には、 たとえそれが情報交換されるものだとしても、 非文字が含まれることを禁止はしないとしています。 ゆえに、 APIプロセス間通信蓄積のような内部的な 「情報交換」 で非文字を正しく保持できるのであると説明されています。 >>38 つまり非文字が利用を認められる「内部処理」 とは、 必ずしも動作中のプロセスが保持するメモリー上の文字列表現のような狭い範囲に限定されていないということです。

[39] Unicode テキストデータ開放型交換では、 非文字の利用は推奨 (recommended) されていません>>38 公開の情報交換では使うべきではありません (should not) >>75 C2

[60] ところでこの開放型、非開放型という区別は、 ライブラリーIPCWeb API など多様な手法で作者の異なる多数のソフトウェア部品を組み合わせて構築する現代的なアプリケーション開発技法のもとでは、 不鮮明かもしれません。 各部分で非文字がどう扱われるか、 正確に把握しながら開発する人は、そう多くはないでしょう。 いつどこでどのように扱われるかわからないとすると、 ごく限られた小さな関数内部でのみ使うような極めて限定的な用法以外は安全とはいえません。


[4] HTML では、 著者文書非文字を含めてはなりません。 直接の記述も文字参照としての記述もできません。 HTML Standard

[6] XML では、 U+FFFEU+FFFF文書に含めると整形式ではなくなります。 それ以外の非文字を含めることはできますが、 仕様書の Note で非推奨 (discouraged) とされています。 >>62, >>63 XMLにおける文字

[65] JavaScript では非文字を扱うことができます。 DOM非文字を含めることもできます。 (DOM としてメモリー上で非文字を保持することは可能ですが、 HTML文書XML文書として直列化すると、 不適合になります。)

処理

[33] 非文字は処理系依存の意味を割り当てても良いことになっています。 従って内部でどのように処理されるかはまったく不明です。

[76] ただし処理は、 非文字符号点抽象文字と解釈してはなりません。 >>75 C2

[67] そして、 非文字が含まれる文字列を受信したとき、 その挙動はまったく不明です。 ある実装では正しく扱える文字列が他の実装では意図せぬ動作を招くおそれがあります。

[47] The Unicode Standard として、 アプリケーション開放型情報交換非文字を受信した時に、 非文字をどう解釈しなければならないといった定めはありません。 しかし非文字U+FFFD に置き換えるなど適切な措置をとるのよい慣習 (good practice) とされます。 ただし削除するだけだとセキュリティーの問題を起こすおそれがあります。 >>38

[34] とはいえ多くの実装は非文字に特別な意味を与えておらず、 プロトコルによっては誤りとして扱われたり、 U+FFFD に置き換えられたりする他は、 普通の未割り当ての符号位置と同じように扱われることが多いようです。

[68] アプリケーション非文字に特別な意味を与えている場合は、 外部から与えられた非文字の意味がそれと一致している保証が無い限り、 U+FFFD に置き換えるか受け入れを拒絶するなど適切な措置を採らないと、 誤動作してしまいます。 ときにはセキュリティー問題となるかもしれません。

[69] アプリケーションソフトウェア部品の中には、 非文字が与えられた時、 致死的エラーとして扱うものがあります。 開発者が意図せずそのような挙動のライブラリーを組み込んでいる場合もあります。 利用者がその挙動を完全に把握できているならいいですが (そんなことはほぼ無い)、 悪意ある第三者が非文字の入ったデータを混入させる DoS攻撃に使うおそれがあります。


[61] HTML構文解析器は、 非文字構文解析誤りとし、 U+FFFD に置き換えなければなりません HTML Standard文字参照U+FFFD に置き換えられます。

[64] 従って構文解析直後の HTML DOM には非文字は含まれません。 ただしスクリプトDOM を操作して非文字を挿入することはできます。 従って JavaScript のコードは非文字が含まれないことを前提にはできません。

[66] XML構文解析器U+FFFE, U+FFFF に遭遇したとき、 これを非整形式として扱わなければなりません。 そこで構文解析を停止し、 致死的エラーとして扱っても構いません (そのような実装が多いです) が、 処理を継続することも認められています。 ただしその場合どのように処理されるかは定められていません。 それ以外の非文字は、 通常の文字と同じように扱わなければなりません。

[70] 正当な利用者が意図せずに、 または悪意ある攻撃者により、 データに U+FFFEU+FFFF が混入させられ、 XML文書である RSSフィード非整形式化される事案がままあります。 (いけてないフィードリーダーはそのようなフィードを扱えないのです。)

関連

[21] 制御文字U+FEFF ZWNBSP文字であり、非文字ではありません。

[22] BOM符号化方式に依存したビット組合せであり、 文字でも非文字でも、符号位置でもありません。 (The Unicode Standard文字であるかのように扱っていますが。)

歴史

U+FDD0 - U+FDEF

[16] U+FDD0 - U+FDEF の 32個の符号位置は、 Unicode 3.1非文字とされました。

U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, ..., U+FFFFE, U+FFFFF, U+10FFFE, U+10FFFF

[17] Unicode 3.1 はこれら32符号位置Unicode 3.0 で既に非文字であったとしていますが、 Unicode 3.0 のどの部分でそのように規定されているのか確認できませんでした。

There are 34 specific code points in Unicode 3.0 that are characterized as noncharacters.

[18] これら32符号位置非文字として code charts にはじめて掲載されたのは Unicode 3.1 です。 (それ以前はサロゲート部分の code charts がありませんでした。)

[25] Unicode ML の発言 (>>26) によれば、これらが追加されたのは ISO/IEC 10646 の規定があったためであり、それが発見された時には既に遅かった、ということです。

[27] ISO/IEC 10646-1:2000 に対応する JIS X 0221-1:2001 の 7. には、

いかなるでも、符号位置FFFE 及び FFFF を使用してはならない。

... とあります。 ISO/IEC 10646-1:2000 は Unicode 3.0 に相当しています。 これが Unicode でも非文字として扱わなければならなくなった根拠でしょう。

[28] ISO/IEC 10646-1:1993 から既にこの規定があったのかは未確認です。

[29] FFFEUCS-4 BOM における誤認を防ぐためと説明できます (ただし BOM が導入されたのと FFFE が予約されたのでどちらが先かは不明)。

[30] FFFF が予約されている理由は不明です。

[23] unicode - What's the purpose of the noncharacters U+FDD0 to U+FDEF? - Stack Overflow ( ( 版)) http://stackoverflow.com/questions/5188679/whats-the-purpose-of-the-noncharacters-ufdd0-to-ufdef

[24] Unicode Character Encoding Stability Policy ( ( 版)) http://unicode.org/policies/stability_policy.html#Property_Value

[35] Define control and noncharacter (annevk著, ) https://github.com/whatwg/infra/commit/ad1b87aecce01759096fcdbf6acc2bd6096c3168

[36] Editorial: use noncharacter and control from Infra (annevk著, ) https://github.com/whatwg/html/commit/70925237a88d9802bfe7224fe9c78b146af615be

[37] Editorial: use noncharacter from Infra (annevk著, ) https://github.com/whatwg/url/commit/4a4c55959bec4f091373723bd0d507432d4b3dac

[79] perlunicode - Unicode support in Perl - Perldoc Browser, https://perldoc.perl.org/perlunicode#Noncharacter-code-points