まぜるなきけん (utf8フラグメモ) [Perl]

| コメント(0) | トラックバック(0)

CPANモジュールをアップデートしたらuse utf8してるスクリプトのNet::Twitter経由でのpostが文字化けるようになった。

な... 何を言ってるのか わからねーと思うが (以下略

まぁ、結論から言うと、 戦犯は Net::Twitter だったわけですが。

use strict;
use warnings;
use utf8;
 
use Encode;
use URI;
use URI::Escape;
 
# user code
my %param = ( status => 'てすと' ); # (1)
# Net::Twitter::API::_authorized_request (v3.04003)
utf8::upgrade($_), $_ = encode('utf8', $_) for values %param; # (2)
# URI::_query::query_form 
my @query;
while ( my ($k,$v)=each %param) {
	push @query, "$k=$v"; # (3)
}
my $query = join('&', @query);
my $uri = URI->new('http:');
$uri->query($query);
 
# what I've got
print $uri->query, "\n";
 
# what I want to get
$uri = URI->new('http:');
$uri->query(join('=', status => 'てすと'));
print $uri->query, "\n";

これは今回の問題を簡単に説明するためのコードで、主要なコードを各モジュールから拾ってきたものです。

utf8で保存して実行すると、

status=%C3%A3%C2%81%C2%A6%C3%A3%C2%81%C2%99%C3%A3%C2%81%C2%A8
status=%E3%81%A6%E3%81%99%E3%81%A8

と表示されるはず。
上段が、 use utf8 下で Net::Twitter::update を呼び出した結果サーバに送られるデータと同等のもの(何かよくわからないデータがURI-Encodeされてて文字化けする)。下段が本来送られるべきデータ(UTF-8文字列'てすと'がURI-Encodeされてる)。

なんでこんな変なことになるか

  • (1) の時点では、 hashのkey, value とも utf8-flagged 文字列
  • (2) で、 valueだけ utf8フラグを落とされ、utf8 octet stream になる
  • (3) の文字列 "$k=$v" は utf8-flagged. ただし、 $v は octet stream のまま展開される。この時点で "=" 以降は 'てすと' ではない何か変な文字列になっている。

WORKAROUND

  1. (1) の時点で key を encode_utf8 しておく → (3) の "$k=$v"$k . '=' . $v と等価で、utf8-flag が先頭の $k に合わせられ(?)、全体としてutf8-flagはつかず utf8 octet streamになる。
  2. (2) の時点での encode_utf8 をやめる。→ (3)での文字列結合の結果は utf8-flagged文字列になる
  3. use utf8をやめ、(1)のvalue を decode_utf8 する。 → (3)での文字列結合の結果は utf8 octet stream

まぁ、よく考えたら keyがutf8-flagged でvalue が utf8 octet stream とかいうちぐはぐなことを Net::Twitterがやってるのがよろしくないわけで。そこのところもそっと考えて修正していただきたいところです。

トラックバック(0)

トラックバックURL: http://floralcompany.jp/mt/mt-tb.cgi/34

コメントする

AUTHOR

  • turugina (虎王 剱奈)
  • E-mail: turugina {at} floralcompany.jp
  • pixiv
  • PiXA

2012年5月

    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    

アーカイブ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.13-ja

- 警 告 -

本サイトにはいわゆる「18禁画像」(イラスト)へのリンクが存在します。 未成年の方や、その手の画像に不快感を覚える方は、 該当記事(「えちぃの」及び「ちょっとえちぃの」カテゴリ) をご覧にならないようお願いいたします。

上記を理解した上で非表示のブログパーツを表示する
あわせて読みたいブログパーツ
ついった
drawr/pixiv/twitpic