BOM sniffing

符号化と復号 (文字コード)

[47] 符号化は、文字列バイト列に変換する操作です。 復号は、バイト列文字列に変換する操作です。

仕様書

符号化

[45] 符号化は、文字列を何らかのバイト列に変換する操作です。

[40] 符号化 (encode) は、 符号位置ストリームストリーム文字符号化符号化について、 次のようにします >>1

  1. [41] 出力を、バイトストリームに設定します。
  2. [42] 符号化符号化器クラス走らせます。 入力ストリーム出力出力とし、 誤りモードhtml とします。
  3. [43] 出力を返します。

[44] replacementUTF-16BEUTF-16LE符号化とすることはできません >>1

[53] 符号化は、次の場面で用いられます。

[79] 符号化が呼び出される場面

[46] この操作は、 Encoding Standard の規定する任意の文字符号化への符号化が必要な場合に使います。 これは後方互換性のため必要な場面に限定されています。 新しい文脈では UTF-8符号化などを用いるのが望ましいと考えられています >>1

復号

[33] 復号は、何らかのバイト列文字列に変換する操作です。

[37] この操作は、引数として文字符号化を引き渡すことができます。 しかし入力に BOM が含まれていれば、そちらが優先されます (BOM sniffing)。

[38] HTTP 仕様上は charset 引数文字符号化の指定が BOM より優先されることになっていますが、現実にはそれでは相互運用性に問題があります。 これは意図的違反です >>1
[83] charset 引数で指定されるのは符号化ラベルであり、 呼び出し側で適切な文字符号化に変換してから本操作を呼び出す必要があります。

[3] 復号 (decode) は、 バイトストリームストリーム符号化符号化について、 次のようにします >>1

  1. [4] バッファーを、空のバイト列に設定します。
  2. [6] 繰り返し、ストリーム読みバッファーの末尾に追加します。バッファーが3バイトとなるか、 end-of-stream が得られた時点でやめます。
  3. [7] バッファーの最初の3バイトが 0xEF 0xBB 0xBF なら、
    1. [8] 符号化を、 UTF-8 に設定します。
  4. [10] それ以外で、バッファーの最初の2バイトが 0xFE 0xFF なら、
    1. [11] 符号化を、 UTF-16BE に設定します。
    2. [5] バッファーが3バイトなら、
      1. [9] バッファーの最後のバイトを、ストリームprependします。
  5. [13] それ以外で、バッファーの最初の2バイトが 0xFF 0xFE なら、
    1. [14] 符号化を、 UTF-16LE に設定します。
    2. [35] バッファーが3バイトなら、
      1. [36] バッファーの最後のバイトを、ストリームprependします。
  6. [34] それ以外なら、
    1. [32] バッファーを、ストリームprependします。
  7. [12] 出力を、符号位置ストリームに設定します。
  8. [16] 符号化復号器クラス走らせます。 入力ストリーム出力出力とします。
  9. [17] 出力を返します。

[31] 仕様書にはありませんが、符号化も返す必要があります。

[57] TextDecoder インターフェイスdecode メソッド >>56 は、その復号の処理の部分について、引数として

復号器オブジェクト
復号器オブジェクト
ストリーム
ストリーム
誤りモード
誤りモード (replacement または fatal)
do not flush flag
フラグ
BOM無視フラグ
フラグ
... を受け取り、次のようにします。
  1. [58] 出力を、新しいストリームに設定します。
  2. [59] 繰り返し、
    1. [60] 字句を、ストリーム読んだ結果に設定します。
    2. [61] 字句end-of-stream で、 do not flush flagなら、
      1. [63] 繰り返しをここで脱出します。
    3. [62] それ以外なら、
      1. [64] 結果を、復号器オブジェクト処理の結果に設定します。 入力ストリーム出力出力誤りモード誤りモードとします。
      2. [65] 結果により、
        終了済み
        繰り返しをここで脱出します。
        誤り
        TypeError投げ、ここで停止します。
  3. [67] ストリームの直列化 (serialize stream) 、すなわち、
    1. [66] ストリームを、 end-of-stream が得られるまで読み続けます。 結果を、得られた符号位置を順に連結したものに設定します。
    2. [68] 復号器オブジェクトUTF-8UTF-16BEUTF-16LE のいずれかで、 BOM無視フラグなら、
      1. [69] 結果の先頭が U+FEFF なら、これを除去します。
    3. [70] 結果を返します。

[71] この操作は、文字列の境界以外で分割されているかもしれない複数のバイト列を連続する1つの文字列として処理することや、 BOM の扱いを著者が指示することを想定し、他での処理よりも複雑となっています。

[84] 実際には、復号操作やUTF-8復号および関連各操作も、 入出力が1つのバイト列文字列ではなくストリームとなる場合があり、 この操作と同じような形で実装することになると思われます。


[72] 復号操作は、次の場面で使われています。

[73] バイト列復号して文字列を得る場面
c
場面
spec
仕様書上の操作
stream
ストリーム出力
legacy
UTF-8
bom
BOM
user
上書き指定
ctmeta
内容型メタデータ
sniffing
charset sniffing
default
既定の符号化
change
符号化の変更
error
誤りモード
c
TextDecoder
spec
TextDecoder
stream
legacy
error
指定可
c
TextDecoder (ignoreBOM)
spec
TextDecoder
stream
legacy
bom
除去
error
指定可
c
HTML構文解析器
spec
復号
stream
legacy
bom
sniffing
ctmeta
sniffing
HTML
user
default
1. 親閲覧文脈 2. UA依存
change
error
replacement
c
XHR 文書応答 (HTML)
spec
復号
legacy
ctmeta
user
bom
sniffing
sniffing
XHR HTML
default
UTF-8
error
replacement

# HTML Imports

c
XML構文解析器
stream
legacy
bom
sniffing
ctmeta
sniffing
XML
default
UTF-8
user
error
(fatal)
#
navigate, XSLT, responseXML, document.load
c
CSS構文解析器 (文書から)
spec
復号
legacy
bom
sniffing
ctmeta
sniffing
CSS
default
1. charset 2. 文書
error
replacement
c
CSS構文解析器 (CSS から)
spec
復号
legacy
bom
sniffing
ctmeta
sniffing
CSS
default
CSS
error
replacement
c
CSS構文解析器 (Link: から)
spec
復号
legacy
bom
sniffing
ctmeta
sniffing
CSS
default
UTF-8
error
replacement
c
テキストファイルのDOM構築
stream
legacy
bom
sniffing
ctmeta
sniffing
MIME型依存
default
MIME型依存
user
error
replacement
c
XHR テキスト応答 (XML)
spec
復号
stream
legacy
bom
sniffing
ctmeta
sniffing
XML
default
UTF-8
user
error
replacement
c
XHR テキスト応答 (非 XML)
spec
復号
stream
legacy
bom
sniffing
ctmeta
default
UTF-8
sniffing
BOM
user
error
replacement
c
fetch package data テキスト
spec
UTF-8復号
bom
除去
error
replacement
c
view-source:
stream
legacy
bom
sniffing
ctmeta
sniffing
MIME型依存
default
MIME型依存
user
error
replacement
c
クリップボードから貼り付け
legacy
MIME型プラットフォーム依存
sniffing
MIME型プラットフォーム依存
default
MIME型プラットフォーム依存
c
古典スクリプトのfetch
spec
復号
stream
legacy
bom
sniffing
ctmeta
sniffing
BOM
default
1. <script charset> 2. 文書
error
replacement
c
スクリプトのfetch (古典スクリプトのfetch以外)
spec
UTF-8復号
stream
bom
除去
error
replacement
c
javascript:
spec
UTF-8復号
bom
除去
error
replacement
c
XHR JSON応答
spec
UTF-8復号 (バイト群からJSONを構文解析)
bom
除去
error
replacement
c
fetch package data JSON
spec
UTF-8復号 (バイト群からJSONを構文解析)
bom
除去
error
replacement
c
application/manifest+json
spec
UTF-8復号
bom
除去
error
replacement
c
payment-method-manifest
spec
UTF-8復号
bom
除去
error
replacement
c
PushMessageData
spec
UTF-8復号
bom
除去
error
replacement
c
WebDriver 要求 JSON
c
Source Map
c
document.cookie
spec
BOMなしUTF-8復号
error
replacement
c
challenge realm
c
Content-Disposition: filename
c
Closeフレーム reason
spec
BOMなしUTF-8復号
error
replacement
c
Web Transport Processing WebSocket テキストフレーム
spec
TextDecoder
stream
bom
除去
error
replacement
c
text/event-stream
spec
UTF-8復号
stream
bom
除去
error
replacement
c
ホスト構文解析器
spec
BOMなしUTF-8復号 (BOMなしUTF-8復号または失敗)
error
replacement (fatal)
c
パーセント復号
spec
BOMなしUTF-8復号
error
replacement
c
decodeURI
spec
Decode()
error
URIError
c
decodeURIComponent
spec
Decode()
error
URIError
c
文書の示された部分決定
spec
BOMなしUTF-8復号
error
replacement
c
file: URL path
c
application/x-www-form-urlencoded
spec
BOMなしUTF-8復号 (旧: 復号)
legacy
error
replacement
c
媒体素片
spec
UTF-8復号
error
fatal
c
[91] multipart/form-data
spec
BOMなしUTF-8復号
stream
legacy
bom
除去
error
replacement
c
parse a manifest
spec
UTF-8復号
bom
除去
error
replacement
c
m3u8
c
WebVTT構文解析器
spec
UTF-8復号
stream
bom
除去
error
replacement
c
文字列 (X.500)
c
MIME型をバイト列から構文解析
spec
同型復号
c
URL構文解析器
spec
同型復号
c
data: URL処理器
spec
同型復号
c
Refresh:
spec
同型復号
c
get, decode, and split (Content-Type:, X-Content-Type-Options: など)
spec
同型復号
c
atob
spec
同型復号
c
Web Transport Processing 環境変数の値
spec
復号
legacy
bom
除去
error
replacement

[39] 復号操作は、 Encoding Standard の任意の文字符号化からの復号のために使えます。 これは後方互換性のため必要な場面に限られます。 新しい文脈では UTF-8復号を用いるのが望ましいと考えられています >>1

[81] UTF-8復号は、復号操作を呼び出さず、 直接復号器を呼び出しています。


[80] HTML, XHR 文書応答 HTML, XML, script (古典スクリプト), CSS, テキスト文書, XHR テキスト応答の各場面での文字コードの判定方法をまとめると、 次のようになります。

  1. BOM sniffing (certain)
  2. 上書き指定
  3. HTTP charset (certain)
  4. prescan
    1. [HTML] prescan (tentative)
    2. [XHR 文書応答 HTML] XHR HTML prescan (certain)
    3. [XML] XML prescan
    4. [CSS] CSS prescan
  5. 環境符号化 (明示的)
    1. [script] <script charset>
    2. [CSS] <link charset>
    3. [CSS] <?xml-stylesheet charset?>
  6. 環境符号化 (暗示的)
    1. [HTML] 親閲覧文脈 (tentative)
    2. [HTML] 履歴 (tentative)
    3. [CSS] 読み込み元スタイルシート符号化
    4. [CSS, script] 文書の文字符号化
  7. [HTML, テキスト文書] UNIVCHARDET (tentative)
  8. [HTML, テキスト文書] 利用者ロケール (tentative)
  9. UTF-8
    1. [HTML, テキスト文書] (tentative)
    2. [XHR 文書応答 HTML] (certain)

[89] charset sniffing に使うデータの長さについては、資源ヘッダーを参照。


[82] HTML StandardHTML構文解析器a known definite encoding を指定可能であり、 XHR文書応答HTML の場合にこれが使われます。 文書応答は、 HTML構文解析器の標準の (navigate で使われる) encoding sniffing algorithm のかわりに、独自の簡略化されたアルゴリズムを使っています。

符号化器と復号器

[49] Encoding Standard は、符号化器復号器を、 文字符号化ごとに定義されるクラス的なものと、 その実現値たる個別のオブジェクト的なものの両方の意味で使っています。

[52] 符号化器クラス復号器クラスには、 走らせる処理と取扱器が定義されています。 また復号器クラスBOMを持つは、当該復号器文字符号化UTF-8UTF-16BEUTF-16LE のいずれかならで、それ以外ならです。

[2] 符号化器オブジェクト復号器オブジェクトは、 いくつかの文字符号化依存の状態を持ちます。 また、処理演算が定義されています。

[50] 更に、 Web IDLインターフェイスとして TextEncoderTextDecoder があり、それぞれ (通常の Web IDLインターフェイス同様に) インターフェイスオブジェクト (≒ クラス) とオブジェクトが存在しています。

[51] TextEncoderTextDecoderオブジェクトは、 いくつかの状態を持ちます。それには符号化器オブジェクト復号器オブジェクトも含まれます。 同時には1つのオブジェクトだけを持ちますが、時に新しいオブジェクトに差し替えられることがあります。

[21] 符号化符号化器クラスまたは復号器クラスを、 ストリーム入力ストリーム出力誤りモードモードについて走らせる (run) には、 次のようにします >>15

  1. [22] オブジェクトを、の新しい実現値オブジェクトに設定します。
  2. [23] 繰り返し、
    1. [24] 結果を、処理の結果に設定します。
      オブジェクト
      オブジェクト
      字句
      入力読んだ結果
      入力
      入力
      出力
      出力
      モード
      モード
    2. [25] 結果継続以外なら、
      1. [26] 結果を返し、ここで停止します。

[27] 符号化器オブジェクトまたは復号器オブジェクトオブジェクトを、 字句字句ストリーム入力ストリーム出力誤りモードモードについて処理 (process) するには、 次のようにします >>15

  1. [28] 結果を、入力字句についてオブジェクトクラス取扱器を実行した結果に設定します。
  2. [29] 結果により、
    継続終了済み
    結果を返し、ここで停止します。
    1つ以上字句
    結果出力pushします。
    誤り
    モードにより、
    replacement
    U+FFFD出力pushします。
    html
    &#結果符号位置十進数ASCII数字で最短で表現したもの、 ; を連結したものを入力prependします。
    fatal
    誤りを返し、ここで停止します。
  3. [30] 継続を返します。

[54] 処理は、走らせるの他に、 TextEncoderencode メソッドでも呼びだされます。しかしUTF-8符号化 (間接的に走らせるを呼び出します。) と実質的に等価です。

[19] 符号化器復号器取扱器 (handler) は、 ストリーム字句を入力とします。 次のいずれかを返します。 >>15

[48] 具体的なアルゴリズムは、文字符号化ごとに規定されています。

文字符号化の項を参照。

文脈

[18] 符号化は、符号化器 (encoder) クラス復号器 (decoder) クラスを持ちます >>15

ただし置換UTF-16BEUTF-16LE符号化器クラスを持ちません >>15

誤りモード

[20] 誤りモード (error mode) は、次のいずれかです >>15

replacement (復号器既定値)
不正な入力を U+FFFD に置換することを指定するものです。
fatal (復号器 / 符号化器既定値)
不正な入力の時エラーを報告して停止するべきことを指定するものです。
html (符号化器)
出力の文字符号化で表現できない時 HTML十進文字参照に置換することを指定するものです。

[75] fatal は、 XML構文解析器 >>15BOMなしUTF-8復号または失敗TextDecoder fatal で使われます。

[78] replacement はその他の復号が必要な場面で使われます。 例えばHTML構文解析器が該当します。

[74] 符号化器では実際には html しか使われません。 かつては TextEncoderUTF-8 以外かつ fatal が指定される可能性があったようですが、現在では UTF-8 しか指定できません。 また UTF-8 はすべてのUnicodeスカラー値誤りなく符号化できます。

サロゲートWeb IDL USVString への変換の時点で置換されます。

歴史

[76] Define 'continue' and 'break' statements (mikewest著, ) https://github.com/whatwg/infra/commit/8fbf990dcdb5f7ee80a85b569cba61a056fe1cc5

[77] Parse application/x-www-form-urlencoded using UTF-8 only (annevk著, ) https://github.com/whatwg/url/commit/3fe969679f78c92c353047661b0c4b6797f099f6

[90] Give clearer advice on hooks for standards (annevk著, ) https://github.com/whatwg/encoding/commit/b579018b406d7752f8b7a3aa9c2bc800519c6f1a

[92] Use UTF-8 decode without BOM for multipart/form-data (annevk, , ) https://github.com/whatwg/fetch/commit/7db8ac52245d6f0abaaeec6ae1cd96553c30b737