Cookieで得た全角文字をCGIで変換したい

[上に] [前に] [次に]
omi 1998/12/07(月) 03:22:09
wwwcount.cgi のログ項目に、投稿時 Cookie に残した名前を
入れようと
$Tname =getCookie('Tname');
$Tname =~ tr/+/ /;
$Tname =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
とするんですが、
山田 が %u5C71%u7530 となって、変換してくれません。
$Tname =~ s/%u([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9])/pack('S', hex($1))/eg;
では、山田 が q\0u になります。
基本的な知識がスッポリ抜けているのでお手上げです。
よろしくご指導ください。

B-Cus 1998/12/07(月) 03:38:25
> 山田 が %u5C71%u7530 となって、

これ、Unicodeですよね。

一応変換コマンドを持っているのですが、変換テーブルがかなりでかいです。
他にいい方法がなかったら送りますので言ってください。

B-Cus 1998/12/07(月) 03:46:27
> $Tname =~ s/%u([a-fA-F0-9][a-fA-F0-9][a-fA-F0-9][a-fA-F0-9])/pack('S', hex($1))/eg;
> では、山田 が q\0u になります。

Uniocdeと既存のコード(SJIS、JIS、EUC)の間には、規則的な変換方法は
存在しません。でっかい変換テーブルを使って、1文字ずつ変換する
しかないです。

で、質問。どうやったらデータがUnicodeになってしまうんでしょうか?
NN4/IE4でも、フォームに入れた日本語はJIS/SJIS/EUCとして送られる
はずですよね。cookieだけブラウザが勝手にUnicodeに変換してしまう
のでしょうか。もしそうなら、ちゃんとURLエンコードしたものを
set-cookie:すれば大丈夫ではないかと思うんですが。

omi 1998/12/07(月) 15:29:07
NC4.06 だと正常で、$Tname =~ /〜/eg; がなくても 山田 と表示されました。
容疑者の iE のバージョンは4.72.3110.1 です。

B-Cus さん
set-cookie: するイメージがつかめないのですが、
各ページからは<IMG src='wwwcount.cgi?hide+dmy.gif' height=1>
だけで CGI を起動してカウントアップとログ記録をしています。

実行ファイルは、各ページから毎回呼ばれるので、ソースの大きさを、
6.5k までシェイプアップしたのに 変換テーブルは重すぎます。

"/usr/local/bin/nkf";#プロバイダが用意している漢字コード変換コマンド
が使えるといいですね。

getCookie が犯人とは思えませんが表しておきます。
sub getCookie {
if ( $ENV{'HTTP_COOKIE'}) {
  for $yy (split(/; */, $ENV{'HTTP_COOKIE'})) {
   ($name, $value) = split(/=/, $yy);
   $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C",hex($1))/eg;
   $COOKIE{$name} = $value;
  }
  $ENV{'HTTP_COOKIE'} ='';
 }
 return($COOKIE{$_[0]});
}

omi 1998/12/07(月) 15:29:11
NC4.06 だと正常で、$Tname =~ /〜/eg; がなくても 山田 と表示されました。
容疑者の iE のバージョンは4.72.3110.1 です。

B-Cus さん
set-cookie: するイメージがつかめないのですが、
各ページからは<IMG src='wwwcount.cgi?hide+dmy.gif' height=1>
だけで CGI を起動してカウントアップとログ記録をしています。

実行ファイルは、各ページから毎回呼ばれるので、ソースの大きさを、
6.5k までシェイプアップしたのに 変換テーブルは重すぎます。

"/usr/local/bin/nkf";#プロバイダが用意している漢字コード変換コマンド
が使えるといいですね。

getCookie が犯人とは思えませんが表しておきます。
sub getCookie {
if ( $ENV{'HTTP_COOKIE'}) {
  for $yy (split(/; */, $ENV{'HTTP_COOKIE'})) {
   ($name, $value) = split(/=/, $yy);
   $value =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("C",hex($1))/eg;
   $COOKIE{$name} = $value;
  }
  $ENV{'HTTP_COOKIE'} ='';
 }
 return($COOKIE{$_[0]});
}

omi 1998/12/07(月) 15:31:41
あちゃー

B-Cus 1998/12/07(月) 15:56:06
えっと、僕が疑っているのはgetcookieではなく、

> 投稿時 Cookie に残した名前を入れようと

の部分です。「Set-cookie: ....」というのを出力しているのは
誰でしょうか。その時点で既にUnicodeになっていませんか?
# でもNCならOK、ということは違うかな…。

あと、どこかのファイルに保存されているIEのcookieデータを
直接見ることはできませんか?

ちなみに、JIS→Unicode変換プログラムは
 http://www.cs.gunma-u.ac.jp/~j5306050/j2uc.c
こんな感じです。ほとんどが変換テーブルです。
今回はこの逆のプログラムを書けばいいわけです。

omi 1998/12/07(月) 18:21:55
B-Cus さん、調べました。
問題の Cookie をセットしたのは、

function setCookie(key,val){
s1=key+'='+escape(val)+'; '
s1+='expires=Fri, 11-Nov-2011 02:11:11; ';
document.cookie=s1;
}
です。

cookieデータは
NNでは 山田 → %8ER%93c
iEでは 山田 → %u5C71%u7530
になります。
escape() unescape() を抜くと
NN は 山田 → q0
iE は 山田表示可能 → 山田表示可能
になります。
(山田さんは不愉快ですね。すいまんでした)

どうも、iE4 の escape() が犯人のようですね。
他のビルトイン関数があるといいんですが。

iE の時は
s1=key+'='+val+'; '
にすればうまく行くでしょう。ちょっと迷うのは、
if(NN) val=escape(val); なのか、if(!iE)〜 なのか、です。
他のブラウザで、エラーしたら変えればいいことですが。

たすかりました。 ありがとうございます。

omi 1998/12/07(月) 18:22:46
[[解決]]
これをチェックしなくちゃ

[上に] [前に] [次に]