EC-CUBEのセッション管理に関する不具合を見つけた

EC-CUBEのセッション管理に関する不具合を見つけた

eccube

今までも不思議に思うことは多々あったのですが、EC-CUBEのセッション管理には不具合があるのを見つけてしまいました
MAX_LIFETIME(デフォルトだと7200秒)よりも早いタイミングでセッションが消えてしまう可能性があります

問題のコード

この問題はMySQLの場合のみ発生します

data/class/helper/SC_Helper_Session.php
~~~
function sfSessGc($maxlifetime) {
// MAX_LIFETIME以上更新されていないセッションを削除する。
$objQuery =& SC_Query_Ex::getSingletonInstance();
$where = “update_date < current_timestamp + '-". MAX_LIFETIME . " secs'"; $objQuery->delete(‘dtb_session’, $where);
return true;
}
~~~

この「current_timestamp + ‘-“. MAX_LIFETIME . ” secs’」が問題になります

PostgreSQLの場合

正しく2時間前の時間が指定されます

~~~
# select current_timestamp,current_timestamp + ‘-7200 secs’ ;
now | current_timestamp + ‘-7200 secs’
——————————-+——————————-
2013-03-08 15:03:59.121512+09 | 2013-03-08 13:03:59.121512+09
(1 row)
~~~

MySQLの場合

結果が文字列になっててわかりにくいのでcastしたものも追加してあります

~~~
select current_timestamp,current_timestamp + ‘-7200 secs’, cast(current_timestamp + ‘-7200 secs’ as datetime);
+———————+———————————-+—————————————————-+
| current_timestamp | current_timestamp + ‘-7200 secs’ | cast(current_timestamp + ‘-7200 secs’ as datetime) |
+———————+———————————-+—————————————————-+
| 2013-03-08 15:07:02 | 20130308143502 | 2013-03-08 14:35:02 |
+———————+———————————-+—————————————————-+
1 row in set, 2 warnings (0.00 sec)
~~~

2時間前にならずに2013-03-08 14:35:02(約30分前)の時間になってしまいました
これは、MySQLとPostgreSQLのSQLの書き方に違いがあるために起こっていることです

修正方法

MySQLを使っている人はこう書き換えればPostgreSQLと同じ結果になります

data/class/helper/SC_Helper_Session.php
~~~
function sfSessGc($maxlifetime) {
// MAX_LIFETIME以上更新されていないセッションを削除する。
$objQuery =& SC_Query_Ex::getSingletonInstance();
//$where = “update_date < current_timestamp + '-". MAX_LIFETIME . " secs'"; $where = "update_date < current_timestamp + interval -". MAX_LIFETIME . " second"; $objQuery->delete(‘dtb_session’, $where);
return true;
}
~~~

SQLで書くとこうなります
~~~
mysql> select current_timestamp,current_timestamp + interval -7200 second;
+———————+——————————————-+
| current_timestamp | current_timestamp + interval -7200 second |
+———————+——————————————-+
| 2013-03-08 15:14:01 | 2013-03-08 13:14:01 |
+———————+——————————————-+
1 row in set (0.00 sec)
~~~

自分でコミットすればいいんですが、コミッターのアカウントもパスワードもやる気も無くしちゃったので誰か開発合宿で直してコミットしておいてください(^_^;)
確認した範囲ではEC-CUBE2.4.4系から最新の2.12系まですべて影響を受けているものと思われます

参考サイト:【第34回】MySQLの日付計算 – Tech [Friday] プロモバイルエンジニアブログ

21:32 追記

早速コミットしてもらえたので次のバージョンあたりでは直っていそうです
http://svn.ec-cube.net/open_trac/changeset/22616