CAPTCHAが必要になったので、とりあえずZendFramework内を模索するとあった。これはないだろうとなんとなく思ってたのでよかったよかったと思ってたら、こいつは使い物にならなかった。
なぜなら、CAPTCHAで表示されている文字と入力文字が一致しているかどうかを検証するメソッドがバグっているから。
なぜなら、CAPTCHAで表示されている文字と入力文字が一致しているかどうかを検証するメソッドがバグっているから。
いろいろやっててうごかねーなーと思って、ソースを探索していくとひどいものを発見。
現時点のZFのバージョンが1.7。そのアーカイブの中に含まれているソースがこれ。
/**
* Validate the word
*
* @see Zend_Validate_Interface::isValid()
* @param mixed $value
* @return boolean
*/
public function isValid($value, $context = null)
{
$name = $this->getName();
if (!isset($context[$name]['input'])) {
$this->_error(self::MISSING_VALUE);
return false;
}
$value = strtolower($context[$name]['input']);
$this->_setValue($value);
if (!isset($context[$name]['id'])) {
$this->_error(self::MISSING_ID);
return false;
}
$this->_id = $context[$name]['id'];
if ($value !== $this->getWord()) {
$this->_error(self::BAD_CAPTCHA);
return false;
}
return true;
}
引数が2つあって、$valueがユーザーの入力値で、もういっこ$contextってのがオプショナルで存在する。=nullってことは$contextはなくてもよいケースがあるってことだけど、ここでびっくり8行目あたりで検証対象であるところの$valueがオプショナルの$contextの値で上書きされている。
こんなひどいバグは絶対問題になっているだろうと思ってJIRAに障害で上がっているかどうか確認しようとしたらあったあった。
うわー。もめてるよ。もめてるっていうのかどうかわからないけど、Otaさんという人が僕からすると明らかに正しい指摘をしているのだけど、Matthewさんという人が理解してないんだか意固地になってんだか、とにかく反発しているという状況。
どうやらこのロジックはZend_Formと連携すると動くらしいんだけど、それでも
・オプショナルな引数が必須というソースの矛盾
・だからドキュメントもおかしい
・つーかZend_Form前提っていうこと自体がZFの思想とあってなくね?
という俺から言わせたらバグを抱えているわけです。
でも、この問題、JIRA上では解決したことになっているから最終的には直ったのかなあ、と思ってSVN上の最新バージョンを見てみた。
/**
* Validate the word
*
* @see Zend_Validate_Interface::isValid()
* @param mixed $value
* @return boolean
*/
public function isValid($value, $context = null)
{
if (!is_array($value) && !is_array($context)) {
$this->_error(self::MISSING_VALUE);
return false;
}
if (!is_array($value) && is_array($context)) {
$value = $context;
}
$name = $this->getName();
if (isset($value[$name])) {
$value = $value[$name];
}
if (!isset($value['input'])) {
$this->_error(self::MISSING_VALUE);
return false;
}
$input = strtolower($value['input']);
$this->_setValue($input);
if (!isset($value['id'])) {
$this->_error(self::MISSING_ID);
return false;
}
$this->_id = $value['id'];
if ($input !== $this->getWord()) {
$this->_error(self::BAD_CAPTCHA);
return false;
}
return true;
}
うーん。$valueが配列に変わってる。POSTデータをまるごと渡す仕様になったらしい。
たぶんそれって以前のオプショナルの役割だったようで、なるほどオプショナルを必須にしたのか。
でも、それだと以前の$valueの立場ってなんなんだろうって思うけど。
つーとフォーム上のキャプチャのnameはinputにしなくちゃいけないってことなのかな?それはいやだなあ。つーか使い方がもはやわからねー。しかも問題は解決したことになってるし。
Otaさんがいっていた予言は的中した。
I guess normal user will fall into dispair when trying to use Zend_Image_Captcha.
コメントする