From: "NARUSE, Yui" Date: 2006-08-18T13:50:51+09:00 Subject: [ruby-dev:29307] Re: CGI#out で MIMEエンコード文字列がデコードされる 成瀬です。 CGI#out で NKF を使うか使わないかについては特に意見はありません。 とみたまさひろ wrote: > とみたです。 > > On Fri, 18 Aug 2006 10:38:00 +0900 > とみたまさひろ wrote: > >> やっぱり、UTF-8 の時に NKF 使うのはやめませんか? なんか他にもまだ想定 >> していない問題がありそうで…。 > > こんな問題が出ました。ソースも charset も UTF-8 なのに、コードが妙に変 > 換されてしまっています。 > > Ruby 1.8.4 > > $ echo | ruby -rcgi -e 'CGI.new.out("charset"=>"utf-8"){"\xef\xbc\x8d\xef\xbd\x9e\xef\xbf\xa0\n"}' | tail -1 | od -tx1 > 0000000 ef bc 8d ef bd 9e ef bf a0 0a > 0000012 > > Ruby 1.8.5 Preview 4 > > $ echo | /usr/local/bin/ruby -rcgi -e 'CGI.new.out("charset"=>"utf-8"){"\xef\xbc\x8d\xef\xbd\x9e\xef\xbf\xa0\n"}' | tail -1 | od -tx1 > 0000000 e2 88 92 e3 80 9c c2 a2 0a > 0000011 > > ということで、NKF 使うのやめましょう。 > > --- ruby-1.8.5/lib/cgi.rb.orig 2006-08-18 01:25:13.000000000 +0900 > +++ ruby-1.8.5/lib/cgi.rb 2006-08-18 11:33:04.000000000 +0900 > @@ -716,8 +716,6 @@ > when /shift_jis/ni > content = NKF::nkf('-s -m0', content) > options["language"] = "ja" unless options.has_key?("language") > - when /utf-8/ni > - content = NKF::nkf('-w -m0', content) > end > end けれど、すでに --no-best-fit-chars とヒントは出ているのですから、 その辺は試して欲しいものです。 --no-best-fit-chars Unicode からの変換の際に、往復安全性が確保さ れ ない文字の変換を行いません。 Unicode から Unicode の変換の際に -x と共に指定す る と、 nkf を UTF 形式の変換に用いることができま す。(逆に言えば、これを指定しないと一部の文 字が保存されません) パスに関わる文字列を変換する際には、このオプ ションを指定することを強く推奨します。 http://sourceforge.jp/projects/nkf/document/nkf-man-2_0_6-ja/ja/4/nkf-man-2_0_6-ja.txt ですね。 動作としては WideCharToMultiByte の WC_NO_BEST_FIT_CHARS と同じです。 http://www.microsoft.com/JAPAN/developer/library/jpwinpf/_win32_widechartomultibyte.htm 解説しますと、 そもそもの前提として、日本語で用いられる文字 - JIS X 0208 の、 Unicode との対応は定まったものではありません。 そのさまざまな JIS - Unicode 間の変換のうち、メジャーなものとして、 JIS の変換表を ASCII の範囲は変えないという変更を加えたものと、 Microsoft の用いている変換表 (CP932 シリーズ) があります。 nkf 2.0.7 では入力としては双方を受け入れ、 デフォルトではある種の正規化を行い、 デフォルトで JIS 風に出力します。 そのため、先の例では U+FFF5 を受け入れ、U+301C を出力しています。 なので、先の例で意図した出力を得るには、 1. nkf 内部でのある種の正規化を行わない → --no-best-fit-chars 2. 出力を CP932 風にする → --cp932 のどちらかを指定する、ということになります。 ただ、その「意図している出力」が「正しい出力」かは難しいところです。 ユーザ側が JIS 風の Unicode と CP932 風の Unicode、 どちらを求めているかはわたしには判断できません。 Windows な人は CP932 風でないと読めない文字もありますが、 他の環境のことはわからないので・・・。 -- NARUSE, Yui DBDB A476 FDBD 9450 02CD 0EFC BCE3 C388 472E C1EA