セキュリティ・キャンプ2014 Webセキュリティクラスに応募したことと Vim の話です。
応募したことと Vim の話なので、応募用紙の内容の話ではないです。
さて、自分は応募用紙を全世界で愛されているエディタであるところのVimで書いたのですが、Vimがなにやら色々と妙な挙動を示しました。
応募用紙 (テキスト版) を開いて、とりあえず 5. を見たところ、ちょっと違和感のある部分がありました。
if( !url.match( /^https?:¥/¥// ) ) return "/"; ^ ^ こいつら
日本語版 Windows じゃないのにバックスラッシュ(0x5C)が円記号(0xA5)になってる!! なんだこれは!!
hexdump で見るとこの位置には 0x5C があるので、謎はますます深まるばかりです。未だに解決してません。
vim -u NONE でこのファイルを開いたら、A5 にはならなかった (し、文字化けした) ので、どうも文字コードのまわりの処理がクサそうです。
検証のため、日本語版 Windows 7 の notepad.exe でバックスラッシュ(見た目円記号)が含まれるファイルを作成して、Linux上のVimに持ってきましたが、0xA5にはなりませんでした。誰か教えてください。
それともう一点。Vim でこの応募用紙を開いた時、UTF-8 なファイルだと認識したようでした。自分はそれを露ほども疑わずに最初から最後までVimで書き通し、確認もVimでしたのですが、提出後に添付したファイルを念のためGmailからダウンロードし、gedit で開いたところ文字化け!! そこに、ちょうどこんな感じのツイートが目に入り、大慌てです。
セキュリティキャンプの応募用紙、毎年数名、暗号化してたりエンコードしてたり難読化してたりと凝った体裁で送ってくる人がいますけれど、よっぽどヒマでない限りはそういうのは読み飛ばしちゃうので、ふつうに平文で書いてくださいね。
— Yosuke HASEGAWA (@hasegawayosuke) June 16, 2014
ウヒョー。もう提出期限は過ぎてしまっていたのですが、念のため事務局の方に連絡したところ、向こうでは正しく開けていたようです。
nkf -g したところ、Shift_JIS と guess されましたし、hexdump で覗いても中身は Shift_JIS でした。どうして Vim は UTF-8 だと思っているファイルに Shift_JIS で書き込んだのでしょうか。これも誰か教えてください……。
おしまい。通っていますように。
日本語版 Windows ではなくても、0x5C に円記号がマッピングされている日本語用のフォントであれば円記号が表示されます。
hexdump しなくても、Vim 上で ga と操作するとカーソル位置の文字コードが見れますのでお試し下さい。
もしかしたらフォント以外の要因、OS のロケールなどで円記号に表示されているかもしれません。興味深いですので
使用されているフォントと OS を教えていただけないでしょうか。
vim -u NONE で開いた際に文字化けを起こしているのは不可解なところですが、-iconv な Vim であればそういう挙動を示すかもしれません。:ver でビルドセット、ビルドオプションを確認されると手がかりになると思います。
ところで、Vim でこの応募用紙を開いた時、UTF-8 なファイルだと認識したようだという根拠はどういった点でしょうか。
私の手元では vim -u NONE したところ、cp932 (windows の Shift_JIS に対応するコードマップだが、厳密には一部異なる) として判定されています。
vim には内部処理用のエンコーディングとファイル自体のエンコーディング設定があり、内部処理用のエンコーディングは
windows を除く近年の OS だとデフォルトで utf-8 となっていることがほとんどです。これは :set encoding? で確認できます。
一方ファイルのエンコーディングは :set fileencoding? で確認します。ご存知でしたら恐縮ですが、これらを間違えてご確認されているということはありませんか。
コメントありがとうございます。
環境の話ですが、Ubuntu 14.04、LANG=en_US.UTF-8、フォントは Ricty です。Vim は Ubuntu のリポジトリから引っ張ってきたものです。
普通にバックスラッシュを入力すると円記号ではなくバックスラッシュが出力されるので、日本語版 Windows のように表示上の問題だけ、ということはないと思います。
hexdump したというのは、Vim で見るとこの文字は本当に 0xA5 になってしまっているからです (ga で確認しても A5 になっています) 。非常に不思議ですが、どうやら置換されてしまっているような感じです。
ファイルのエンコーディングですが、 :set fileencoding? したところ、sjis になっていました。ステータスバーにエンコーディングを出して確認したつもりになっていましたが、どうやらこれは encoding のほうだったようです。ありがとうございます。
:ver の結果です。
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Jan 2 2014 19:39:32)
Included patches: 1-52
Modified by pkg-vim-maintainers@lists.alioth.debian.org
Compiled by buildd@
Huge version without GUI. Features included (+) or not (-):
+acl +cmdline_info +emacs_tags -hangul_input +menu +mouse_xterm -python3 +syntax +virtualedit -xsmp
+arabic +comments +eval +iconv +mksession +multi_byte +quickfix +tag_binary +visual -xterm_clipboard
+autocmd +conceal +ex_extra +insert_expand +modify_fname +multi_lang +reltime +tag_old_static +visualextra -xterm_save
-balloon_eval +cryptv +extra_search +jumplist +mouse -mzscheme +rightleft -tag_any_white +viminfo -xpm
-browse +cscope +farsi +keymap -mouseshape +netbeans_intg -ruby -tcl +vreplace
++builtin_terms +cursorbind +file_in_path +langmap +mouse_dec +path_extra +scrollbind +terminfo +wildignore
+byte_offset +cursorshape +find_in_path +libcall +mouse_gpm -perl +signs +termresponse +wildmenu
+cindent +dialog_con +float +linebreak -mouse_jsbterm +persistent_undo +smartindent +textobjects +windows
-clientserver +diff +folding +lispindent +mouse_netterm +postscript -sniff +title +writebackup
-clipboard +digraphs -footer +listcmds +mouse_sgr +printer +startuptime -toolbar -X11
+cmdline_compl -dnd +fork() +localmap -mouse_sysmouse +profile +statusline +user_commands -xfontset
+cmdline_hist -ebcdic +gettext -lua +mouse_urxvt +python -sun_workshop +vertsplit -xim
system vimrc file: "$VIM/vimrc"
user vimrc file: "$HOME/.vimrc"
2nd user vimrc file: "~/.vim/vimrc"
user exrc file: "$HOME/.exrc"
fall-back for $VIM: "/usr/share/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
Linking: gcc -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed -o vim -lm -ltinfo -lnsl -lselinux -lacl -lattr -lgpm -ldl -L/usr/lib/python2.7/config-x86_64-linux-gn
u -lpython2.7 -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions