Zend\Session\Storage\AbstractSessionArrayStorage::fromArray() can receive a string causing a fatal error on shutdown #4503

Closed
gws opened this Issue May 18, 2013 · 8 comments

Comments

Projects
None yet
4 participants
@gws
Contributor

gws commented May 18, 2013

Script to reproduce:

<?php

use Zend\Log;
use Zend\Session;

// set up autoloading

Session\Container::setDefaultManager(
    new Session\SessionManager()
);

$logger = new Log\Logger();
$logger->addWriter(new Log\Writer\Syslog());

Log\Logger::registerErrorHandler($logger);

trigger_error('This is a warning.', E_USER_WARNING);

Results:

PHP Catchable fatal error: Argument 1 passed to Zend\Session\Storage\AbstractSessionArrayStorage::fromArray() must be of the type array, string given, called in [snip]vendor/zendframework/zendframework/library/Zend/Session/SessionManager.php on line 167 and defined in [snip]vendor/zendframework/zendframework/library/Zend/Session/Storage/AbstractSessionArrayStorage.php on line 209

$_SESSION contains what appears to be the session information as a serialized string (JSON?) rather than an array on line 167.

  • When I do not explicitly set the default session manager, I can't reproduce the issue.
  • When I sub out the Syslog writer for, say, a Mock writer, I can't reproduce the issue.
  • When I do not trigger the error handler at the end, but instead just log something, I can't reproduce the issue.

Version information (Debian Wheezy):

$ php -v
PHP 5.4.4-14 (cli) (built: Mar  4 2013 14:08:43) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies

Reproducible on ZF 2.1.5 and 2.2.0.

@mwillbanks

This comment has been minimized.

Show comment
Hide comment
@mwillbanks

mwillbanks May 23, 2013

Contributor

Could you show how you are actually doing the autoloading? Are you just including what is in the skeleton ?

The only guess that I would have is that it is attempting to start the session after the trigger error. Are you running this via CLI?

Contributor

mwillbanks commented May 23, 2013

Could you show how you are actually doing the autoloading? Are you just including what is in the skeleton ?

The only guess that I would have is that it is attempting to start the session after the trigger error. Are you running this via CLI?

@gws

This comment has been minimized.

Show comment
Hide comment
@gws

gws May 23, 2013

Contributor

@mwillbanks

Did you have trouble reproducing it?

require_once 'init_autoloader.php';

Just now, in a file called test.php in the root of ZendSkeletonApplication, everything (ZSA, dependencies) updated as of today.

I am running it from the CLI.

Contributor

gws commented May 23, 2013

@mwillbanks

Did you have trouble reproducing it?

require_once 'init_autoloader.php';

Just now, in a file called test.php in the root of ZendSkeletonApplication, everything (ZSA, dependencies) updated as of today.

I am running it from the CLI.

@mwillbanks

This comment has been minimized.

Show comment
Hide comment
@mwillbanks

mwillbanks May 23, 2013

Contributor

I didn't try it yet; I just wanted to make certain that I had the exact test case and things that you were doing so that I could easily reproduce it and see where it is causing it.

Contributor

mwillbanks commented May 23, 2013

I didn't try it yet; I just wanted to make certain that I had the exact test case and things that you were doing so that I could easily reproduce it and see where it is causing it.

@mwillbanks

This comment has been minimized.

Show comment
Hide comment
@mwillbanks

mwillbanks Jun 4, 2013

Contributor

Does this only happen on the CLI? I'm having a hard time figuring out why this is a JSON serialized string... I am digging through this right now :)

Contributor

mwillbanks commented Jun 4, 2013

Does this only happen on the CLI? I'm having a hard time figuring out why this is a JSON serialized string... I am digging through this right now :)

@mwillbanks

This comment has been minimized.

Show comment
Hide comment
@mwillbanks

mwillbanks Jun 4, 2013

Contributor

It's actually a PHP serialized string... i have not been able to find the source of why it is happening although - i might need to put xdebug in here to give me a better idea of how this exception is happening.

Contributor

mwillbanks commented Jun 4, 2013

It's actually a PHP serialized string... i have not been able to find the source of why it is happening although - i might need to put xdebug in here to give me a better idea of how this exception is happening.

@gws

This comment has been minimized.

Show comment
Hide comment
@gws

gws Jun 4, 2013

Contributor

@mwillbanks I hadn't tried reproducing it without the CLI SAPI. However, with the same file I was running from the CLI, I fired up PHP's built-in webserver and got an identical error report.

In the root of ZendSkeletonApplication, where my uniquely and creatively named file resides:

php -S localhost:8000 test.php

The reason I didn't think it was a PHP-serialized string was the lack of types, but I didn't want to throw you off by stating that it absolutely had to be JSON even though it looked like it to me (hey, you never know), so sorry for the confusion :)

echo serialize(["foo", 2, 3]);

// I'd expect a PHP-serialized string to look more like this:
// a:3:{i:0;s:3:"foo";i:1;i:2;i:2;i:3;}

// var_dump($_SESSION) on line 167 of Zend/Session/SessionManager.php (after session_write_close()):
// string(53) "{"__ZF":"{\"_REQUEST_ACCESS_TIME\":1370330325.8725}"}"
//
// The above blows up because the next line expects an array and gets a string.

Thanks again for taking a look at this.

Contributor

gws commented Jun 4, 2013

@mwillbanks I hadn't tried reproducing it without the CLI SAPI. However, with the same file I was running from the CLI, I fired up PHP's built-in webserver and got an identical error report.

In the root of ZendSkeletonApplication, where my uniquely and creatively named file resides:

php -S localhost:8000 test.php

The reason I didn't think it was a PHP-serialized string was the lack of types, but I didn't want to throw you off by stating that it absolutely had to be JSON even though it looked like it to me (hey, you never know), so sorry for the confusion :)

echo serialize(["foo", 2, 3]);

// I'd expect a PHP-serialized string to look more like this:
// a:3:{i:0;s:3:"foo";i:1;i:2;i:2;i:3;}

// var_dump($_SESSION) on line 167 of Zend/Session/SessionManager.php (after session_write_close()):
// string(53) "{"__ZF":"{\"_REQUEST_ACCESS_TIME\":1370330325.8725}"}"
//
// The above blows up because the next line expects an array and gets a string.

Thanks again for taking a look at this.

@CrispCreations

This comment has been minimized.

Show comment
Hide comment
@CrispCreations

CrispCreations Jun 4, 2013

Just thought I'd mention it, session data isn't serialized using serialize(), if you're using the php default session.serialize_handler, it's done using session_encode(). That said, the string that @gwis has pasted doesn't look right, I'd expect something like __ZF|a:1:{s:20:"_REQUEST_ACCESS_TIME";d:1368712919.8600039;} but the data types a:1:, s:20: and d: seem to be missing

Just thought I'd mention it, session data isn't serialized using serialize(), if you're using the php default session.serialize_handler, it's done using session_encode(). That said, the string that @gwis has pasted doesn't look right, I'd expect something like __ZF|a:1:{s:20:"_REQUEST_ACCESS_TIME";d:1368712919.8600039;} but the data types a:1:, s:20: and d: seem to be missing

@gws

This comment has been minimized.

Show comment
Hide comment
@gws

gws Jun 8, 2013

Contributor

@mwillbanks in my testing, this is fixed by zendframework#4609

Contributor

gws commented Jun 8, 2013

@mwillbanks in my testing, this is fixed by zendframework#4609

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment