fetus Diary
2008/02/04(月) - SQLStatement@Mojavi 2
今時 Mojavi 2 使うなという話は置いておいて…。昔作ったプログラムのバグ改修なので。
Mojavi 2 の SQLStatement::prepare がバグってる疑惑。
修正後:
function & prepare ($statement) {
if (sizeof($this->attributes) > 0) {
// replace conversion character values
// cannot set the call back object in this constructor,
// so it must be set here
$this->pattern->setCallbackObject($this, 'callback');
$this->pattern->setPattern($statement);
$statement =& $this->pattern->parse();
}
$this->stat = $statement;
if (strpos($statement, '?') !== FALSE) {
// replace prepareable values
$count = strlen($this->stat);
$index = -1;
$oldStatement = $this->stat;
$statement = '';
// loop through statement
for ($i = 0; $i < $count; $i++) {
if ($oldStatement{$i} == '?') {
$index++;
if (isset($this->values[$index])) {
$statement .= $this->values[$index];
} else {
$error = 'SQL statement does not contain a value for ' .
'preparable index #' . ($index + 1);
trigger_error($error, E_USER_ERROR);
}
} else {
$statement .= $oldStatement{$i};
}
}
}
return $statement;
}
オリジナルのコードでは、最初の if(sizeof($this->attributes) > 0) ブロックが return $statement の直前に。要はこれ、順番入れ替えただけ。
なんでこんなことしなくちゃいけないかと言うと、この prepare 関数、%a{data_col} みたいなのを置き換える処理が入ってるのね。これが最初の if ブロックの内側(実際に処理しているのは、$this->pattern->parse())。
"%" がキーになっているのが重要。
ここで、プレースホルダ(SQL 中の "?")に置換設定した文字列中に例えば「100%発生する」とかいう文章があった場合、先に "?" の中身が展開されてしまっていたので、この "%" に誤爆して文字化けしてしまう。
本当はこの修正でも、%x{} で置き換えられた文字列中に? が混入しているとバグるから宜しくない。まじめに両方同時にやるのが正解。
- 08/02/04
18:0723:07
コメント
コメントはありません。