Skip to content

Corrupted session written when there's a fatal error in autoloader #12504

@ssigwart

Description

@ssigwart

Description

Create two files in the same directory:

index.php

<?php

class TestSessionHandler implements SessionHandlerInterface
{
	public function close(): bool
	{
		return true;
	}
	public function destroy(string $id): bool
	{
		return true;
	}
	public function gc(int $max_lifetime): int|false
	{
		return 0;
	}
	public function open(string $path, string $name): bool
	{
		return true;
	}
	public function read(string $id): string|false
	{
		// Return a session object that has 3 variables
		return 'before|i:1234;test|O:4:"Test":0:{}after|i:5678;';
	}
	public function write($id, $data): bool
	{
		echo 'Write session:' . PHP_EOL;
		echo $data . PHP_EOL;
		return true;
	}
}

session_set_save_handler(new TestSessionHandler());

// Autoload class that's in session
spl_autoload_register(function() {
	require_once(__DIR__ . '/Test.class.php');
	return true;
});

// If you use this line, the session still fails to load, but the session will not be written back, which is ideal
// require_once(__DIR__ . '/Test.class.php');

header('Content-type: text/plain');
session_start();
print_r($_SESSION);

Test.class.php

<?php

class Test
{
	// The `= null` results in a fatal error
	public int $var = null;
}

When running index.php, it will result in a fatal error. However, it will also write a session with all variables before the invalid Test class set to zero and no variables after the $_SESSION['test']. You can see that in the output:

<br />
<b>Fatal error</b>:  Default value for property of type int may not be null. Use the nullable type ?int to allow null default value in <b>/path/to/dir/Test.class.php</b> on line <b>5</b><br />
Write session:
before|i:0;

If you uncomment the second require_once so that the autoloader doesn't need to run, it still results in the fatal error as expected, but it does not write back to the session.

I know that avoiding the fatal error is a workaround, but if this can be fixed, it could prevent corrupting user sessions if bad code gets deployed to production.

PHP Version

PHP 8.0.30

Operating System

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions