input type=file の挙動については JavaScript の問題ではないが、JavaScript に渡された file path の処理に絡むので JavaScript 関連の話題として取り上げた。 調査対象は、下のような input type=file を使った form がある場合、ボタンの onClick で呼ばれる JavaScript の関数には、file path がどのような文字列として渡されるか、である。この file path は local machine 上で使われるだけだが、path 文字列を利用した処理(例えば server 上に保存する場合の file name の default 値を決めるなど)がある場合に、field separater がどの文字かを確認する必要がある。 ここで OS, browser 依存性が(例によって)出てくるので、それについて以下にまとめた。
調査には上記のように、input type=button の onClick から func() を呼ぶ form を用いた。 この form で選択するファイル名は、escape の状況などを確認するために field separater や escape に使われる文字を含む「/情%報 \部@a:b&」というものとした。 ただし Mac OS 9.x/X ではファイル名に ":" は使えないので、「/情%報 \部@a-b&」というファイル名を、Windows の場合には "/", "\", ":" が使えないので「-情%報 -部@a-b&」というファイル名を使用した。 func() の内容は基本的には alert( document.fileform.filename.value ); と同値だが、escape 検知のために '%', '&', '\' の置換を噛ませた(下記参照)。 ただし、以下の結果のうち「func() に渡されている文字列」欄には、置換前の文字列を表示している。
function func(){ var str1 = document.fileform.filename.value str1 = str1.replace( /:/g, "*" ); str1 = str1.replace( /%/g, "-" ); str1 = str1.replace( /&/g, "=" ); str1 = str1.replace( /\\/g, "_" ); alert( str1 + "\n" + document.fileform.filename.value ); }
各 OS, browser ごとに
を、以下の表にまとめた。
OS | browser | input type=file の表示 | alert() の表示 | escape() した結果 | func() に渡されている文字列 |
---|---|---|---|---|---|
Mac OS 9.2.2 (HD 直下の tmp の中の hoge.txt を選択) | Netscape 4.76 | /情%報 \部@a-b& | /MacintoshHD/tmp/:情%報 \部@a-b& | /MacintoshHD/tmp/%3A%8F%EE%25%95%F1%20%5C%95%94%40a-b%26 | /MacintoshHD/tmp/%3A%8F%EE%25%95%F1%20%5C%95%94%40a-b%26 |
Netscape 6.1 | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD%3Atmp%3A/%BE%F0%25%CA%F3%20%5C%C9%F4%40a-b%26 (EUC-JP) MacintoshHD%3Atmp%3A/%8F%EE%25%95%F1%20%5C%95%94%40a-b%26 (Shift-JIS) MacintoshHD%3Atmp%3A/%1B%24B%3Ep%1B%28B%25%1B%24BJs%1B%28B%20%5C%1B%24BIt%1B%28B%40a-b%26 (ISO-2022-JP) | MacintoshHD:tmp:/情%報 \部@a-b& | |
Netscape 7.02 | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD%3Atmp%3A/%BE%F0%25%CA%F3%20%5C%C9%F4%40a-b%26 (EUC-JP) MacintoshHD%3Atmp%3A/%8F%EE%25%95%F1%20%5C%95%94%40a-b%26 (Shift-JIS) MacintoshHD%3Atmp%3A/%1B%24B%3Ep%1B%28B%25%1B%24BJs%1B%28B%20%5C%1B%24BIt%1B%28B%40a-b%26 (ISO-2022-JP) | MacintoshHD:tmp:/情%報 \部@a-b& | |
Mozilla 1.0rc2 | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD%3Atmp%3A/%BE%F0%25%CA%F3%20%5C%C9%F4%40a-b%26 (EUC-JP) MacintoshHD%3Atmp%3A/%8F%EE%25%95%F1%20%5C%95%94%40a-b%26 (Shift-JIS) MacintoshHD%3Atmp%3A/%1B%24B%3Ep%1B%28B%25%1B%24BJs%1B%28B%20%1B%28J%5C%1B%24BIt%1B%28B%40a-b%26 (ISO-2022-JP) | MacintoshHD:tmp:/情%報 \部@a-b& | |
Mozilla 1.2.1 | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD:tmp:/情%報 \部@a-b& | MacintoshHD%3Atmp%3A/%BE%F0%25%CA%F3%20 (EUC-JP) MacintoshHD%3Atmp%3A/%8F%EE%25%95%F1%20 (Shift-JIS) MacintoshHD%3Atmp%3A/%1B%24B%3Ep%1B%28B%25%1B%24BJs%1B%28B%20%1B%(ここではみ出た) (ISO-2022-JP) | MacintoshHD:tmp:/情%報 \部@a-b& | |
Internet Explorer 5.0 | /情%報 \部@a-b& | /MacintoshHD/tmp//????@a-b& | /MacintoshHD/tmp//%uFF8F%uFFEE%25%uFF95%uFFF1%20%5C%uFF95%uFF94@a-b%26 | /MacintoshHD/tmp//マ?-ユ? _ユヤ@a-b& (カタカナは半角) | |
Internet Explorer 5.1.7 | /情%報 \部@a-b& | /MacintoshHD/tmp//????@a-b& | /MacintoshHD/tmp//%uFF8F%uFFEE%25%uFF95%uFFF1%20%5C%uFF95%uFF94@a-b%26 | /MacintoshHD/tmp//マ?-ユ? _ユヤ@a-b& (カタカナは半角) | |
Opera 6.03J | "MacintoshHD:tmp:/情%報 \部@a- | "MacintoshHD:tmp:/情%報 \部@a- | "MacintoshHD:tmp:/情%報 \部@a- | ||
iCab 2.8 | /情%報 \部@a-b& | /カ□□ \□@a-b& (カタカナは半角、□は豆腐) | /%8F%EE%25%95%F1%20%5C%95%94@a-b%26 | /カ□□ \□@a-b& (カタカナは半角、□は豆腐) | |
iCab 2.97 | /情%報 \部@a-b& | /カ□□ \□@a-b& (カタカナは半角、□は豆腐) | /%8F%EE%25%95%F1%20%5C%95%94@a-b%26 | /カ□□ \□@a-b& (カタカナは半角、□は豆腐) | |
Mac OS X 10.2 (home dir の hoge.txt を選択) | Netscape 7.0 | Macintosh HD:Users:satodai:/情%報 \部@a-b& | Macintosh HD:Users:satodai:/情%報 \部@a-b& | Macintosh%20HD%3Atmp%3A/%BE%F0%25%CA%F3%20%5C%C9%F4%40a-b%26 (EUC-JP) Macintosh%20HD%3Atmp%3A/%8F%EE%25%95%F1%20%5C%95%94%40a-b%26 (Shift-JIS) | Macintosh HD:Users:satodai:/情%報 \部@a-b& |
Mozilla 1.2.1 | Macintosh HD:Users:satodai:/情%報 \部@a-b& | Macintosh HD:Users:satodai:/情%報 \部@a-b& | Macintosh%20HD%3Atmp%3A/%BE%F0%25%CA%F3%20%5C%C9%F4%40a-b%26 (EUC-JP) Macintosh%20HD%3Atmp%3A/%8F%EE%25%95%F1%20%5C%95%94%40a-b%26 (Shift-JIS) | Macintosh HD:Users:satodai:/情%報 \部@a-b& | |
Mozilla 1.4 | /Users/satodai/:情%報 \部@a-b& | /Users/satodai/:情%報 \部@a-b& | /Users/satodai/:情%報 \部@a-b& | ||
Internet Explorer 5.2 | /情%報 \部@a-b& | /Macintosh HD/Users/satodai@a-b& | /Macintosh%20HD/Users/satodai//%uFF8F%uFFEE%25%uFF95%uFFF1%20%5C%uFF95%uFF94@a-b%26 | /Macintosh HD/Users/satodai//マ?-ユ ? _ユ ヤ @a-b& (カタカナは半角) | |
Safari Public Beta | /情%報 \部@a-b& | /Users/satodai/:情%報 \部@a-b& | /Users/satodai/%3A%u60C5%25%u5831%20%A5%u90E8@a-b& | /Users/satodai/:情%報 ¥部@a-b&(¥は半角) | |
Safari 1.1 | /情%報 \部@a-b& | /Users/satodai/:情%報 \部@a-b& | /Users/satodai/:情%報 ¥部@a-b&(¥は半角) | ||
Opera 6.03 | "Macintosh HD:Users:satodai:/情%報 \部@a-b& | "Macintosh HD:Users:satodai:/情%報 \部@a-b& | "Macintosh HD:Users:satodai:/情%報 \部@a-b& | ||
Windows XP Home Edition | Internet Explorer 6.0 sp2 | C:\Program Files\-情%報 -部@a-b& | C:\Program Files\-情%報 -部@a-b& | C:\Program Files\-情%報 -部@a-b& | |
Windows NT 4.0 sp6 | Netscape 6.1 | C:\Program Files\-情%報 -部@a-b& | C:\Program Files\-情%報 -部@a-b& | C%3A%5CProgram%20Files%5C-%BE%F0%25%CA%F3%20-%C9%F4%40a-b%26 (EUC-JP) C%3A%5CProgram%20Files%5C-%8F%EE%25%95%F1%20-%95%94%40a-b%26 (Shift-JIS) | C:\Program Files\-情%報 -部@a-b& |
Internet Explorer 5.5 sp2 | C:\Program Files\-情%報 -部@a-b& | C:\Program Files\-情%報 -部@a-b& | C%3A%5CProgram%20Files%5C-%u60C5%25%u5831%20-%u90E8@a-b%26 | C:\Program Files\-情%報 -部@a-b& |
Netscape 4.76 (Mac OS 9.2.2) では、%HH style の encode(URLencode ではない)済みの文字列が func() に渡されていることが分かる。alert window に表示する際には decode などの処理が入っているようだが、その際に "/" を ":" に置換してしまう bug が見付かった(恐らく field separater を Mac OS style に戻すつもりの処理)。その他の browser では、この種の encode は行われていないようだ。
また Mac OS 版の Netscape 4.x, IE, iCab では file path が unix style に変換されている。これに対して Netscape 6.x, 7.x, Mozilla では Mac OS style のままになっている。また Windows では path 表記の変更は行われてないらしい。
さらに Netscape 6, 7, Mozilla においては、HTML file の文字コード (EUC, Shift-JIS, ISO-2022-JP) によって func() に渡される文字列が異なっていた。どうやら文字コードを考慮した処理は一切なく、byte 列をそのまま渡しているようだ。また、Mozilla 1.2.1 では "\" が escape されないためか、escape() が出力する文字列が "\" の直前で切れていた(他の表示には問題なし)。
Mac OS 版の IE では、alert() が生の日本語を受け取ると alert window で文字化けが起こることが分かっている(alert window への日本語表示)が、今回も同様の現象が確認された。 ただし、escape などの処理は特に行われていないらしい。また、この文字化けが発生していなかった iCab においても、今回は文字化けが発生した。
また Mac 版 IE 5.0 による %uHHHH style の escape() の処理が、Windows 版の IE 5.5 と異なっていることが分かった。Windows 版 IE 5.5 では、UCS-2 文字列に対して escape() 処理が行われているようだ。しかし Mac 版 IE 5.0 では、Shift-JIS で 8FEE である「情」が %uFF8F%uFFEE となっており、RFC 1738 にも ECMA-262 (PDF) にも準拠していない中途半端な処理が行われている。。RFC 準拠であれば %HH style になるはずだし、ECMA-262 準拠であれば、Unicode が使われるべきだ。 なお、Safari Public Beta においては、ECMA-262 準拠の escape() が実装されているようだ。
input type=file の value としてセットされる file path 文字列は、local でのみ使用されるためか、その記法については RFC 1867, HTML 4.01 Specification, DOM Level2 HTML Specification では規定されていないようだ。 このためか、file path には unix style, Mac OS style, DOS style と、いくつかの文字コード(少なくとも EUC-JP, Shift-JIS, ISO-2022-JP, UCS-2)が混在し、それぞれを正しく処理するのが非常に難しくなっている。