3v4l.org

run code in 300+ PHP versions simultaneously
<?php error_reporting(E_ALL & ~E_DEPRECATED); // test serialize() functionality on shutdown register_shutdown_function('shutdown_serialize_test'); function shutdown_serialize_test() { $bug_test = new stdClass(); $bug_test_serialized = serialize([$bug_test, $bug_test]); $bug_test_unserialized = unserialize($bug_test_serialized); if ($bug_test_unserialized === false) { echo "\nserialize() / unserialize() round trip failed on shutdown\n"; } $reference_serialized = 'a:2:{i:0;O:8:"stdClass":0:{}i:1;r:2;}'; if ($bug_test_serialized !== $reference_serialized) { echo "serialize() on shutdown does not match reference:\n"; echo "$bug_test_serialized\n"; echo "should be:\n"; echo "$reference_serialized\n"; } } // records $test into trace function crash_step_1($test) { crash_step_2(debug_backtrace()); } // works on the first trace and serializes it, which triggers the second trace function crash_step_2($trace1) { $new_trace = []; foreach ($trace1 as $traceline) { if (isset($traceline['args'])) { $new_args = []; foreach ($traceline['args'] as $traceline_arg) { $new_args[] = $traceline_arg; } $traceline['args'] = $new_args; // this fails as well # $traceline['args'] = $traceline['args']; } $new_trace[] = $traceline; } return serialize($new_trace); } class class_crash_step_3 { protected function trace2() { $trace2 = debug_backtrace(); $var_list = []; foreach ($trace2 as $traceline) { if (!isset($traceline['args'])) continue; foreach ($traceline['args'] as $tracearg) { $var_idx = false; foreach ($var_list as $found_idx => $var_list_item) { // eventually, this comparison triggers the Fatal error if ($var_list_item === $tracearg) { $var_idx = $found_idx; break; } } if ($var_idx === false) { $var_list[] = $tracearg; } } } } } // this one triggers "Fatal error: Nesting level too deep - recursive dependency?" // and corrupts serialize() during shutdown, also affecting session handlers class class_crash_step_3_variant_A extends class_crash_step_3 implements Serializable { public function serialize() { $this->trace2(); } public function unserialize($data) { } } // interface Serializable is deprecated. with magic methods, corruption does not occur, // but "Fatal error: Nesting level too deep - recursive dependency?" is still triggered class class_crash_step_3_variant_B extends class_crash_step_3 { public function __serialize() { $this->trace2(); } public function __unserialize($data) { } } $test = new class_crash_step_3_variant_A(); #$test = new class_crash_step_3_variant_B(); crash_step_1($test); echo "End of script";
Output for 7.2.33, 8.3.27, 8.4.14
End of script
Output for 8.4.1 - 8.4.13
Fatal error: Uncaught Error: Nesting level too deep - recursive dependency? in /in/9qWTh:60 Stack trace: #0 /in/9qWTh(78): class_crash_step_3->trace2() #1 [internal function]: class_crash_step_3_variant_A->serialize() #2 /in/9qWTh(46): serialize(Array) #3 /in/9qWTh(27): crash_step_2(Array) #4 /in/9qWTh(94): crash_step_1(Object(class_crash_step_3_variant_A)) #5 {main} thrown in /in/9qWTh on line 60
Process exited with code 255.
Output for 8.3.5 - 8.3.26
Fatal error: Nesting level too deep - recursive dependency? in /in/9qWTh on line 60 Warning: unserialize(): Error at offset 36 of 37 bytes in /in/9qWTh on line 10 serialize() / unserialize() round trip failed on shutdown serialize() on shutdown does not match reference: a:2:{i:0;O:8:"stdClass":0:{}i:1;r:9;} should be: a:2:{i:0;O:8:"stdClass":0:{}i:1;r:2;}
Process exited with code 255.
Output for 7.3.0, 8.1.28 - 8.1.33, 8.2.19 - 8.2.29
Fatal error: Nesting level too deep - recursive dependency? in /in/9qWTh on line 60 Notice: unserialize(): Error at offset 36 of 37 bytes in /in/9qWTh on line 10 serialize() / unserialize() round trip failed on shutdown serialize() on shutdown does not match reference: a:2:{i:0;O:8:"stdClass":0:{}i:1;r:9;} should be: a:2:{i:0;O:8:"stdClass":0:{}i:1;r:2;}
Process exited with code 255.

preferences:
84.61 ms | 411 KiB | 5 Q