XSSフィルタ部分に脆弱性が見つかり、CodeIgniter 2.0.2がリリースされました。ただ、CSRF関連のバグが新たに発生しているようです。アップグレードについては十分注意してください。
2.0.1と2.0.2のdiffを見てみたところ、
- Security.phpがcoreに移動
- doctypes.php、smileys.php、foreign_chars.php、user_agents.php、mimes.php、routes.php、hooks.php、constants.phpが環境切り分けに対応
- ENVIRONMENT定数の存在チェック追加
- Cacheまわりのクラス名にCI_プレフィックスが付与
と言った感じでした。
Cacheまわりのクラス名にCI_プレフィックスが付与という事だったので、ついに継承を考慮されたのかと思い、前回、[CodeIgniter2.x]Cacheクラスを継承するにはで書いた、Cacheクラスの継承ですが、2.0.2を利用する場合、継承方法がどのように変わったのか試しています。
目次
前回のソースをベースに話をしていきたいと思います。
CI_プレフィックスの付与
まず、Cache.php、Cache/drivers/以下のクラスにCI_プレフィックスが追加されているのでMY_Cacheにも追加します。
application/libraries/Cache/MY_Cache.php
< ?php - class MY_Cache extends Cache { + class MY_Cache extends CI_Cache { |
application/libraries/MY_Cache/drivers/MY_Cache_memcached.php
< ?php require_once BASEPATH.'libraries/Cache/drivers/Cache_memcached.php'; - class MY_Cache_memcached extends Cache_memcached { + class MY_Cache_memcached extends CI_Cache_memcached { |
この状態で動かすと下記のようなエラーになります。また、その際のログです。
An Error Was Encountered Unable to load the requested driver: MY_Cache_memcached
INFO - 2011-04-08 10:47:41 --> load driver=application/libraries/my_cache/drivers/My_cache_memcached.php INFO - 2011-04-08 10:47:41 --> load driver=application/libraries/my_cache/drivers/my_cache_memcached.php INFO - 2011-04-08 10:47:41 --> load driver=/home/tatsuya/Dropbox/www/ci202_cache/system/libraries/my_cache/drivers/My_cache_memcached.php INFO - 2011-04-08 10:47:41 --> load driver=/home/tatsuya/Dropbox/www/ci202_cache/system/libraries/my_cache/drivers/my_cache_memcached.php ERROR - 2011-04-08 10:47:41 --> Unable to load the requested driver: MY_Cache_memcached
以前と読み込み場所が変わっていますね。前回までの構造は、
./ |-- Cache | `-- MY_Cache.php |-- MY_Cache | `-- drivers | |-- MY_Cache_apc.php | |-- MY_Cache_dummy.php | |-- MY_Cache_file.php | `-- MY_Cache_memcached.php `-- index.html
となっていましたので、読み込み場所の指定方法が変わったようです。
Driver.phpのCI_対応
system/libraries/Driver.php
2.0.1の頃と比べると$lib_nameや$child_classがstrtolowerされているので、上記のように小文字のディレクトリを読み込み対象とするようになりました。
--- CodeIgniter_2.0.1/system/libraries/Driver.php 2011-03-16 02:54:00.000000000 +0800 +++ CodeIgniter_2.0.2/system/libraries/Driver.php 2011-04-07 12:20:00.000000000 +0800 @@ -44,7 +44,11 @@ // The class will be prefixed with the parent lib $child_class = $this->lib_name.'_'.$child; - if (in_array(strtolower($child_class), array_map('strtolower', $this->valid_drivers))) + // Remove the CI_ prefix and lowercase + $lib_name = strtolower(preg_replace('/^CI_/', '', $this->lib_name)); + $driver_name = strtolower(preg_replace('/^CI_/', '', $child_class)); + + if (in_array($driver_name, array_map('strtolower', $this->valid_drivers))) { // check and see if the driver is in a separate file if ( ! class_exists($child_class)) @@ -52,19 +56,15 @@ // check application path first foreach (array(APPPATH, BASEPATH) as $path) { - // and check for case sensitivity of both the parent and child libs - foreach (array(ucfirst($this->lib_name), strtolower($this->lib_name)) as $lib) + // loves me some nesting! + foreach (array(ucfirst($driver_name), $driver_name) as $class) { - // loves me some nesting! - foreach (array(ucfirst($child_class), strtolower($child_class)) as $class) - { - $filepath = $path.'libraries/'.$this->lib_name.'/drivers/'.$child_class.EXT; + $filepath = $path.'libraries/'.$lib_name.'/drivers/'.$class.EXT; - if (file_exists($filepath)) - { - include_once $filepath; - break; - } + if (file_exists($filepath)) + { + include_once $filepath; + break; } } } |
ディレクトリ、ファイル名を2.0.2に対応
今までの説明を踏まえて、下記のようなディレクトリに変更してみます。
./ |-- Cache | `-- MY_Cache.php |-- my_cache | `-- drivers | |-- My_cache_apc.php | |-- My_cache_dummy.php | |-- My_cache_file.php | `-- My_cache_memcached.php `-- index.html
これで、再度アクセスしてみると無事動くようになりました。
最後に
CI_プレフィックスが付与されていたので、継承を考慮されているのかと思ったのですが、残念ながらまだ中途半端な状態でした。まだまだ、この辺は変更されそうな感じがしますので、継承する場合は激しく自己責任でお願いします。
追記:2011.04.09 18:21
ellislab / CodeIgniter Reactor / issues / #193 – CI_Cache_file — Bitbucket
既に本家に登録されていて対応もされているようですが、上記のDriver.php内の$lib_name変数がstrtolowerされているので、小文字化されてしまっており、読み込み対象のディレクトリも2.0.1のucfirstではなくなっており、正常に読み込めないバグが今回新たに発生しています。対処法としては、下記のように$lib_nameにucfirst実行後の値を代入すれば大丈夫です。
$lib_name = ucfirst(strtolower(preg_replace('/^CI_/', '', $this->lib_name))); |