Details
Description
I believe the session cleanup code in Zend_Session::_processStartupMetadataGlobal () should probably unset ($_SESSION['__ZF'][$namespace]) when ENT timeout hits.
Here is my problem:
I am using Zend_Captcha_Image to generate captchas for my site, and I noticed that if the captchas are not claimed, garbage accumulates in $_SESSION.
Zend_Captcha_Word sets two parameters for the session namespace:
$this->_session->setExpirationHops(1, null, true);
$this->_session->setExpirationSeconds($this->getTimeout());
The resulting session looks like this:
Array
(
[__ZF] => Array
(
[Zend_Form_Captcha_38b0306a2c96d5e34a0abb17cecfb1a8] => Array
(
[ENNH] => 1
[ENT] => 1234830941
)
)
[Zend_Form_Captcha_38b0306a2c96d5e34a0abb17cecfb1a8] => Array
(
[word] => 4ibi7o
)
)
i.e. it sets the session metadata $_SESSION[__ZF][$namespace][ENNH] (number of hops = 1) and $_SESSION[__ZF][$namespace][ENT] (timeout). Now if the captcha is claimed and validated, a new Zend_Session_Namespace object is created and in the constructor, the hop count is decreased and the ENNH parameter is removed, as well as the content $_SESSION[$namespace]. After the timeout, the ENT parameter is removed and $_SESSION[__ZF][$namespace] is cleaned up.
If the captcha is never claimed, the ENT timeout hits, and $_SESSION[__ZF][$namespace][ENT] and $_SESSION[__ZF][$namespace] are removed, but $_SESSION[__ZF][$namespace][ENNH] remains. The cleanup code:
if (isset($namespace) && empty($_SESSION['__ZF'][$namespace])) {
unset($_SESSION['__ZF'][$namespace]);
does not remove $_SESSION['__ZF'][$namespace] because the ENNH parameter is still there. Since the original namespace is never reinstantiated if the user never tries to validate the captcha, garbage accumulates in the session:
Array
(
[__ZF] => Array
(
[Zend_Form_Captcha_695b09f1d32dfc7ea02187e02faa2f91] => Array
(
[ENNH] => 1
)
[Zend_Form_Captcha_d1c1c089bec1e02fc3fb2e75c11a2860] => Array
(
[ENNH] => 1
)
...
}
In long running sessions, this may become substantial.
Now unless there is a compelling reason why the metadata needs to be kept after the content $_SESSION[$namespace] is gone, I believe the session cleanup code in _processStartupMetadataGlobal() should simply unset($_SESSION['__ZF'][$namespace]) after the ENT timeout, so no garbage accumulates in $_SESSION. I even suspect it might be best to simply delete the metadata in all places where $_SESSION[$namespace] is unset (e.g. also when ENNH hits 0).
Sorry if I am missing something.
This was one of the first things I noticed today when trying to implement captchas. I then tried to use my own session instead of letting it create one, but unfortunately there was a bug with setSession/generate as well.