#freeze *decodeの挙動が怪しい? [#fd1fce1b] -ページ: [[BugTrack2]] -投稿者: [[ARAI]] -優先順位: 重要 -状態: 完了 -カテゴリー: 本体バグ -投稿日: 2005-03-06 (日) 16:03:44 -バージョン: 1.4.5rc1 ~ 1.4.5_1 ** 修正 [#xb15887b] - [[cvs:lib/func.php]] (1.34, 1.36-1.38) **メッセージ [#y930c70d] http://cvs.sourceforge.jp/cgi-bin/viewcvs.cgi/pukiwiki/pukiwiki/lib/func.php.diff?r1=1.26&r2=1.27 以降、decodeが期待の動作をしない場合がある?ようです。 簡単な再現例として、[[1.4.5_1におけるPHP>http://pukiwiki.sourceforge.jp/pukiwiki1.4/?PHP]]の「ページ名の変更」を 挙げておきます。 「以下のファイルをリネームします。」の所で、 -[[PHP]]→新ページ名 のように表示されるべきところが、 -→新ページ名 となります。 取り敢えず、decodeをlib/func.php 1.26版に戻すか、 return preg_match('/^[0-9a-f]+$/i', $key) ? pack('H*', "$key") : $key; とすることで回避出来ます。 ---- -お知らせありがとうございます。$keyの値が数字のみの文字列である時の挙動が怪しそうです。どうしてpack() の第二引数をダブルクォーテーションでくくるだけで回避できるのでしょうね (^^; 型の問題(文字列であるかどうか)とは思いますが、マニュアルなど、各種確認します。 -- [[henoheno]] &new{2005-03-27 (日) 16:48:52}; -この挙動は、過去のソースで行われていた処理と同じ事をしても回避できるようです。 -- [[henoheno]] &new{2005-03-27 (日) 17:03:27}; return preg_match('/^[0-9a-f]+$/i', $key) ? substr(pack('H*', '20202020' . $key), 4) : $key; -この処理は [[cvs:func.php]] (r1.30) で追加されていて、そのコミットログに「avoid PHP pack() bug.」とあります。そういう事だったようです (^^; -- [[henoheno]] &new{2005-03-27 (日) 17:08:31}; -で、[[ぱんだ]]さんはこれ(対応)をどこで見つけたのだらう・・・ [[BugTrack/257]] がきっかけの様ですが、それ以上の情報はありませんね。 -- [[henoheno]] &new{2005-03-27 (日) 17:09:26}; -[[PHPfunc:pack]] のコメントをあたっても、特にこの回避策は載っていないようでした。 -- [[henoheno]] &new{2005-03-27 (日) 17:24:36}; -えーと。 --原因1: pack('H*', $key)の$keyが数値のとき、期待した結果が得られません。 ---これについては、そういう仕様なのかどうかはわかりません。 --原因2: rename.inc.phpの290行目あたりで、配列の添え字をそのままpack()に渡しています。 foreach ($pages as $old=>$new) $ret['body'] .= '<li>' . make_pagelink(decode($old)) . [[配列の仕様>http://www.php.net/manual/ja/language.types.array.php#language.types.array.syntax.array-func]]によると >あるキーが、整数の標準的な表現形式である場合、 そのように解釈されます。(つまり、''"8"は 8として解釈されます''。一方、 "08"は"08"として解釈されます。) < --回避方法:decode()関数側で、[[型キャスト>http://www.php.net/manual/ja/language.types.type-juggling.php#language.types.typecasting]]を使って文字列型にキャストしてしまうと間違いないかなと。 return preg_match('/^(?:[0-9a-f]{2})+$/i', $key) ? pack('H*', (string)$key) : $key; --実証コード: <?php $key = strtoupper(bin2hex('PHP')); var_dump($key); // string(6) "504850" $pack = pack('H*', $key); var_dump($pack); // string(3) "PHP" $arr = array($key => 'piyo'); var_dump($arr); // array(1) { // [504850]=> <- ! // string(4) "piyo" // } foreach ($arr as $_key => $_value) { var_dump($_key); // int(504850) <- !! } $pack = pack('H*', $_key); var_dump($pack); // string(0) <- !!! $__key = (string)$_key; var_dump($__key); // string(6) "504850" $pack = pack('H*', (string)$_key); var_dump($pack); // string(3) "PHP" ?> -そうか、PHPも型キャストが使えたんだっけか (^^; intで値が来るのには気付いていましたが、配列の仕様通りの動作がきっかけだったのですね。丁寧なコメントありがとうございました。 -- [[henoheno]] &new{2005-03-29 (火) 00:16:03}; -PHP-4.3.11でpack()のバグが直ったらしいです。 -- [[okkez]] &new{2005-04-01 (金) 20:44:28}; #comment