File tree Expand file tree Collapse file tree 3 files changed +82
-6
lines changed Expand file tree Collapse file tree 3 files changed +82
-6
lines changed Original file line number Diff line number Diff line change @@ -35,6 +35,10 @@ PHP NEWS
3535 . Fixed bug GH-13138 (Randomizer::pickArrayKeys() does not detect broken
3636 engines). (timwolla)
3737
38+ - Session:
39+ . Fixed bug GH-12504 (Corrupted session written when there's a fatal error
40+ in autoloader). (nielsdos)
41+
3842- Streams:
3943 . Fixed bug GH-13071 (Copying large files using mmap-able source streams may
4044 exhaust available memory and fail). (nielsdos)
Original file line number Diff line number Diff line change @@ -246,18 +246,28 @@ static zend_string *php_session_encode(void) /* {{{ */
246246}
247247/* }}} */
248248
249+ static ZEND_COLD void php_session_cancel_decode (void )
250+ {
251+ php_session_destroy ();
252+ php_session_track_init ();
253+ php_error_docref (NULL , E_WARNING , "Failed to decode session object. Session has been destroyed" );
254+ }
255+
249256static zend_result php_session_decode (zend_string * data ) /* {{{ */
250257{
251258 if (!PS (serializer )) {
252259 php_error_docref (NULL , E_WARNING , "Unknown session.serialize_handler. Failed to decode session object" );
253260 return FAILURE ;
254261 }
255- if (PS (serializer )-> decode (ZSTR_VAL (data ), ZSTR_LEN (data )) == FAILURE ) {
256- php_session_destroy ();
257- php_session_track_init ();
258- php_error_docref (NULL , E_WARNING , "Failed to decode session object. Session has been destroyed" );
259- return FAILURE ;
260- }
262+ zend_try {
263+ if (PS (serializer )-> decode (ZSTR_VAL (data ), ZSTR_LEN (data )) == FAILURE ) {
264+ php_session_cancel_decode ();
265+ return FAILURE ;
266+ }
267+ } zend_catch {
268+ php_session_cancel_decode ();
269+ zend_bailout ();
270+ } zend_end_try ();
261271 return SUCCESS ;
262272}
263273/* }}} */
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