[PHP-users 12941] Re: wddxについて(一応解決)

Reiji Matsumoto php-users@php.gr.jp
Sun, 2 Feb 2003 18:37:42 +0900


Matsumoto@Spです。

> <php?
>
> てのは、まじすか?
>
> 情報は正確に提供してくださいませ。

たびたびすいませんでした。
今度こそは大丈夫です。このままコピペして実験済です。

■テストプログラムのソース
---------------------------------------------
<?php
$locale = setlocale(LC_ALL,"ja_JP.eucJP");
$a = "赤黒";
$b = wddx_serialize_value($a);
print "locale=[{$locale}]<br><xmp>$b</xmp>";
?>

■実行例1
OS Red Hat Linux 7.0.1J
apache 1.3.24
expat 1.95.2
ブラウザ IE6
---------------------------------------------
locale=[ja_JP.eucjp]

<wddxPacket version='1.0'><header/><data><string>赤黒
</string></data></wddxPacket>
---------------------------------------------

■実行例2
OS NetBSD/i386 1.6
ブラウザ IE6
apache 1.3.26
php 4.2.2
expat 1.95.2 および expat 1.95.4
---------------------------------------------
locale=[C/ja_JP.eucJP/C/C/C/ja_JP.eucJP]

<wddxPacket version='1.0'><header/><data><string><char
code='FFFFFFC0'/><char code='FFFFFFD6'/><char code='FFFFFFB9'/>
<charcode='FFFFFFF5'/></string></data></wddxPacket>
---------------------------------------------

■暫定的解決方法
phpのソースの一部を書き換える事で、一応問題を解決する事が出来ました
ので報告します。

[php-4.2.2の展開ディレクトリ]/ext/wddx/wddx.c

を見てみると、処理中のキャラクターコードの判別に、iscntrl()を利用して
いました。この関数を利用し、制御コードだった場合は、<char code=XXXX />
というパケットを作成し、そうでない場合はそのまま文字コードを出力している
ようです。結局この部分が動作不安定のため、「赤黒」と表示される事もあれ
ば、"<char code=XXXX>"と表示される事もあるという状態のようです。
iscntrl()はロケール依存ですので、この判定を省略してみました。

--- wddx.c(394行) 変更前 ---------------------------
if (iscntrl((int)*p)) {
    FLUSH_BUF();
    sprintf(control_buf, WDDX_CHAR, *p);
    php_wddx_add_chunk(packet, control_buf);
} else
    buf[l++] = *p;

--- wddx.c(394行)変更後 ----------------------------
    buf[l++] = *p;
----------------------------------------------------

これでリコンパイルした所、取りあえず期待する動作になりました。ただし
制御コードの判別を故意に省略してあるので、脆弱性が増しています。
また保守の面でも問題がありますので、抜本的な解決方法も引き続き模索し
ていきたいと思っています。

Matsumoto@Sp