Zend Framework

Set session will be overwritten.

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Critical Critical
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 1.10.0
  • Component/s: Zend_Captcha
  • Labels:
    None

Description

We have setSession() function where we can save the session into the $this->_session, but the generate() function simply overwrites what we kept here: $this->_session. There must be another way to handle this issue. If you protect the $this->_session, then don't provide public setSession().

/**
 * Zend_Captcha_Word
 */

public function setSession(Zend_Session_Namespace $session)
{
	$this->_session = $session;
	return $this;
}

public function generate()
{
	//****//
	$this->_session = null;
	//****//
	$id             = $this->_generateRandomId();
	$this->_setId($id);
	$word           = $this->_generateWord();
	$this->_setWord($word);
	return $id;
}

Activity

Hide
Jonathan Haskins added a comment -

I ran into this bug today and it took me 3 hours of thinking I was doing it wrong before I located the problem in zend. I fixed it by commenting out $this->_session = null;

Show
Jonathan Haskins added a comment - I ran into this bug today and it took me 3 hours of thinking I was doing it wrong before I located the problem in zend. I fixed it by commenting out $this->_session = null;
Hide
Stanislav Malyshev added a comment -

The problem here is that when we use generate(), a captcha with new ID is generated and new session object is created, named by this ID.
However, in many cases isValid() is called before generate() - such as when old captcha failed and we need to generate a new one.
In this case, however, if we keep old session object, then the data will not be written into this object but to the object for the old ID which was created before that, and then when captcha comes back in the next request, it would not be able to find this new object, since only thing it has is the ID, and you didn't write the data into the session with that ID - you wrote it to some other place, with old ID.
setSession() is useful when doing isValid(), but for generate it should create a new session, so you better use _sessionClass if change is needed.

I could however try to fix your use case, but for that I would need some short script demonstrating it, so I could check that both default usage and your scenario works well.

Show
Stanislav Malyshev added a comment - The problem here is that when we use generate(), a captcha with new ID is generated and new session object is created, named by this ID. However, in many cases isValid() is called before generate() - such as when old captcha failed and we need to generate a new one. In this case, however, if we keep old session object, then the data will not be written into this object but to the object for the old ID which was created before that, and then when captcha comes back in the next request, it would not be able to find this new object, since only thing it has is the ID, and you didn't write the data into the session with that ID - you wrote it to some other place, with old ID. setSession() is useful when doing isValid(), but for generate it should create a new session, so you better use _sessionClass if change is needed. I could however try to fix your use case, but for that I would need some short script demonstrating it, so I could check that both default usage and your scenario works well.
Hide
Jonathan Haskins added a comment -

Here's an example of how I am using it (non-working unless commented out as per above). I believe the reason I used a separate session for the captcha is because of ZF-5806.

Controller:
$figlet = array(
'name' => 'captcha',
'wordLen' => 6,
'timeout' => 300,
'outputWidth' => 600,
'font' => '/lib/figlet/univers.flf'
);
$captcha = new Zend_Captcha_Figlet($figlet);
$captcha->setSession(new Zend_Session_Namespace('captcha'));

if ($this->_request->isPost()) {
if ($captcha->isValid($_POST)) { echo 'captcha passed'; }
}

$this->view->captcha_id = $captcha->generate();
$this->view->assign('captcha', $captcha->render(new Zend_View()));

View:
<?=$this->captcha?>
<input type="hidden" name="captcha[id]" value="<?=$this->captcha_id?>" />
<input type="text" name="captcha[input]" size=25 value="">

Show
Jonathan Haskins added a comment - Here's an example of how I am using it (non-working unless commented out as per above). I believe the reason I used a separate session for the captcha is because of ZF-5806. Controller: $figlet = array( 'name' => 'captcha', 'wordLen' => 6, 'timeout' => 300, 'outputWidth' => 600, 'font' => '/lib/figlet/univers.flf' ); $captcha = new Zend_Captcha_Figlet($figlet); $captcha->setSession(new Zend_Session_Namespace('captcha')); if ($this->_request->isPost()) { if ($captcha->isValid($_POST)) { echo 'captcha passed'; } } $this->view->captcha_id = $captcha->generate(); $this->view->assign('captcha', $captcha->render(new Zend_View())); View: <?=$this->captcha?> <input type="hidden" name="captcha[id]" value="<?=$this->captcha_id?>" /> <input type="text" name="captcha[input]" size=25 value="">
Hide
Stanislav Malyshev added a comment -

OK, this should be working in trunk now. Please check if it does what you wanted.

Show
Stanislav Malyshev added a comment - OK, this should be working in trunk now. Please check if it does what you wanted.
Hide
Ota Mares added a comment -

Oh great that this got fixed now, my report was flaged as no issue, whyever.

Show
Ota Mares added a comment - Oh great that this got fixed now, my report was flaged as no issue, whyever.

People

Vote (2)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: