File tree 3 files changed +82
-6
lines changed
3 files changed +82
-6
lines changed Original file line number Diff line number Diff line change @@ -35,6 +35,10 @@ PHP NEWS
35
35
. Fixed bug GH-13138 (Randomizer::pickArrayKeys() does not detect broken
36
36
engines). (timwolla)
37
37
38
+ - Session:
39
+ . Fixed bug GH-12504 (Corrupted session written when there's a fatal error
40
+ in autoloader). (nielsdos)
41
+
38
42
- Streams:
39
43
. Fixed bug GH-13071 (Copying large files using mmap-able source streams may
40
44
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) /* {{{ */
246
246
}
247
247
/* }}} */
248
248
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
+
249
256
static zend_result php_session_decode (zend_string * data ) /* {{{ */
250
257
{
251
258
if (!PS (serializer )) {
252
259
php_error_docref (NULL , E_WARNING , "Unknown session.serialize_handler. Failed to decode session object" );
253
260
return FAILURE ;
254
261
}
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 ();
261
271
return SUCCESS ;
262
272
}
263
273
/* }}} */
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