[php-src] Issue #9708: `object_properties_load` allows `__unserialize` to set wrong property type in GMP, SplFixedArray, etc.

From: Date: Mon, 10 Oct 2022 16:30:30 +0000
Subject: [php-src] Issue #9708: `object_properties_load` allows `__unserialize` to set wrong property type in GMP, SplFixedArray, etc.
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-242568@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/9708 Author: TysonAndre ### Description The following code: ```php <?php class ObjectPropertiesLoadBug extends GMP { public int $a; public int $b; } $ser = 'O:23:"ObjectPropertiesLoadBug":2:{i:0;s:1:"0";i:1;a:2:{s:1:"a";s:8:"NOTANINT";s:1:"b";R:4;}}'; var_dump(unserialize($ser)); echo "Done\n"; ``` Resulted in this output: ``` object(ObjectPropertiesLoadBug)#1 (3) { ["a"]=> &string(8) "NOTANINT" ["b"]=> &string(8) "NOTANINT" ["num"]=> string(1) "0" } php: .../php-src/Zend/zend_execute.c:3653: zend_ref_del_type_source: Assertion `source_list->ptr == prop' failed. [1] 634981 abort (core dumped) php object_properties_load.php ``` But I expected this output instead: ``` Uncaught TypeError: Cannot assign string to property ObjectPropertiesLoadBug::$a of type int ``` This bug probably affects anything using object_properties_load in __unserialize in php 7.4 and newer (including PECLs), where typed properties were first introduced. Related to #9707 The same issue can be reproduced even without references ```php <?php class ObjectPropertiesLoadBug extends GMP { public int $a; } $ser = 'O:23:"ObjectPropertiesLoadBug":2:{i:0;s:1:"0";i:1;a:1:{s:1:"a";s:8:"NOTANINT";}}'; var_export(unserialize($ser)); // expected TypeError /* \ObjectPropertiesLoadBug::__set_state(array( 'a' => 'NOTANINT', )) */ ``` object_properties_load should probably do something similar to the ZEND_ASSIGN_REF, opcode handler and call something similar to zend_assign_to_variable_reference if prop_info has types 1. If the new value is already a reference: delete the original reference in the backing C property table if needed, add that object's property info to the variable's reference group, and then set the typed property to that new reference 2. If the new value was a non-reference: Delete the original reference in the backing C property table if needed, then store the value the way a regular ZEND_ASSIGN_OBJ opcode handler (for property assignment, e.g. $obj->propName = $value;) would behave ### PHP Version 8.1 - 8.3-dev ### Operating System _No response_

« previous php.bugs (#242568) next »