2008.05.23 Friday
PHP での NULLバイトのバイナリデータ生成 〜困ったときの pack関数〜
Flash の特定のアイコンの表示/非表示を管理画面で操作したい, という要望に答えるべく
SWFファイルに変数を埋め込むライブラリを使用させてもらいました。
中身は結構単純で, 変数の key/value の組を SWFファイルのフォーマットに従って特定の領域に格納しているもの。
このライブラリを使って変数を埋め込んでみたのですが, うまく動作しません。
出力されたファイルをバイナリエディタで見てみると, 期待通りの値が出力されていない模様。
$dat = "\x96" . $var1 . "\x00" . $key ."\x00";
のようにバイナリデータを生成してそれをファイルに吐き出しているのですが, どうも "\x00" の扱いがおかしい。
実行してみると, ファイルには何も吐き出されません。
$bin = "\x11\x00\x22\x00\x33\x44\x00\x55";
に変更してみると, 0x11 だけのバイナリデータが生成されました。
どうやら NULLバイト("\x00") で文字列の終わりとみなされて, それ以降に何があっても無視されるみたい。
昔のバージョンの PHP では動作していたけど, (セキュリティがらみの修正で?)どこかのバージョンで挙動が変わったんでしょう。
# $HTTP_GET_VARS とか使ってるし。
さて, 困った。
SWFファイルに変数を埋め込むライブラリを使用させてもらいました。
中身は結構単純で, 変数の key/value の組を SWFファイルのフォーマットに従って特定の領域に格納しているもの。
このライブラリを使って変数を埋め込んでみたのですが, うまく動作しません。
出力されたファイルをバイナリエディタで見てみると, 期待通りの値が出力されていない模様。
$dat = "\x96" . $var1 . "\x00" . $key ."\x00";
のようにバイナリデータを生成してそれをファイルに吐き出しているのですが, どうも "\x00" の扱いがおかしい。
$bin = "\x00\x11\x22\x00\x33\x44\x00\x55";
$fp = fopen('pack.dat', 'w');
fwrite($fp, $bin);
fclose($fp);
実行してみると, ファイルには何も吐き出されません。
$bin = "\x11\x00\x22\x00\x33\x44\x00\x55";
に変更してみると, 0x11 だけのバイナリデータが生成されました。
どうやら NULLバイト("\x00") で文字列の終わりとみなされて, それ以降に何があっても無視されるみたい。
昔のバージョンの PHP では動作していたけど, (セキュリティがらみの修正で?)どこかのバージョンで挙動が変わったんでしょう。
# $HTTP_GET_VARS とか使ってるし。
さて, 困った。
バイナリ操作で困った時は pack関数調べれば何とかなるか...
で, NULLバイトをパックするコードを発見。
pack('x')
で 00 を埋め込むことができます。
ということで, 上記の意図した通りのバイナリファイルを生成するには,
のいずれかで OK。
Webプログラミングはテキスト処理が殆どで, バイナリデータを扱う機会があまりないので馴染みが薄いかも知れませんが, 困ったときは pack関数のマニュアルみれば何とかなります。
...多分(;・∀・)
で, NULLバイトをパックするコードを発見。
pack('x')
で 00 を埋め込むことができます。
ということで, 上記の意図した通りのバイナリファイルを生成するには,
$bin = pack('x') . "\x11\x22" . pack('x') . "\x33\x44" . pack('x') . "\x55";
$bin = pack('xc2', 0x11, 0x22) . pack('xc2', 0x33, 0x44) . pack('xc', 0x55);
$bin = pack('xc2xc2xc', 0x11, 0x22, 0x33, 0x44, 0x55);
のいずれかで OK。
Webプログラミングはテキスト処理が殆どで, バイナリデータを扱う機会があまりないので馴染みが薄いかも知れませんが, 困ったときは pack関数のマニュアルみれば何とかなります。
...多分(;・∀・)









Comments