File tree Expand file tree Collapse file tree 2 files changed +78
-6
lines changed
Expand file tree Collapse file tree 2 files changed +78
-6
lines changed Original file line number Diff line number Diff line change @@ -258,18 +258,28 @@ static zend_string *php_session_encode(void) /* {{{ */
258258}
259259/* }}} */
260260
261+ static ZEND_COLD void php_session_cancel_decode (void )
262+ {
263+ php_session_destroy ();
264+ php_session_track_init ();
265+ php_error_docref (NULL , E_WARNING , "Failed to decode session object. Session has been destroyed" );
266+ }
267+
261268static zend_result php_session_decode (zend_string * data ) /* {{{ */
262269{
263270 if (!PS (serializer )) {
264271 php_error_docref (NULL , E_WARNING , "Unknown session.serialize_handler. Failed to decode session object" );
265272 return FAILURE ;
266273 }
267- if (PS (serializer )-> decode (ZSTR_VAL (data ), ZSTR_LEN (data )) == FAILURE ) {
268- php_session_destroy ();
269- php_session_track_init ();
270- php_error_docref (NULL , E_WARNING , "Failed to decode session object. Session has been destroyed" );
271- return FAILURE ;
272- }
274+ zend_try {
275+ if (PS (serializer )-> decode (ZSTR_VAL (data ), ZSTR_LEN (data )) == FAILURE ) {
276+ php_session_cancel_decode ();
277+ return FAILURE ;
278+ }
279+ } zend_catch {
280+ php_session_cancel_decode ();
281+ zend_bailout ();
282+ } zend_end_try ();
273283 return SUCCESS ;
274284}
275285/* }}} */
Original file line number Diff line number Diff line change 1+ --TEST--
2+ GH-12504 (Corrupted session written when there's a fatal error in autoloader)
3+ --EXTENSIONS--
4+ session
5+ --FILE--
6+ <?php
7+
8+ class TestSessionHandler implements SessionHandlerInterface
9+ {
10+ public function close (): bool
11+ {
12+ return true ;
13+ }
14+ public function destroy (string $ id ): bool
15+ {
16+ return true ;
17+ }
18+ public function gc (int $ max_lifetime ): int |false
19+ {
20+ return 0 ;
21+ }
22+ public function open (string $ path , string $ name ): bool
23+ {
24+ return true ;
25+ }
26+ public function read (string $ id ): string |false
27+ {
28+ // Return a session object that has 3 variables
29+ return 'before|i:1234;test|O:4:"Test":0:{}after|i:5678; ' ;
30+ }
31+ public function write ($ id , $ data ): bool
32+ {
33+ echo 'Write session: ' . PHP_EOL ;
34+ echo $ data . PHP_EOL ;
35+ return true ;
36+ }
37+ }
38+
39+ register_shutdown_function (function () {
40+ echo "In shutdown function \n" ;
41+ var_dump ($ _SESSION );
42+ });
43+
44+ session_set_save_handler (new TestSessionHandler ());
45+
46+ // Autoload class that's in session
47+ spl_autoload_register (function () {
48+ // Easiest way to reproduce the issue is to dynamically define a class with a bogus definition
49+ eval ('class Test {public int $var = null;} ' );
50+ return true ;
51+ });
52+
53+ session_start ();
54+
55+ ?>
56+ --EXPECTF--
57+ Fatal error: Default value for property of type int may not be null. Use the nullable type ?int to allow null default value in %s on line %d
58+
59+ Warning: Unknown: Failed to decode session object. Session has been destroyed in Unknown on line 0
60+ In shutdown function
61+ array(0) {
62+ }
You can’t perform that action at this time.
0 commit comments