Open
Description
Description
The following code:
<?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
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
- 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
- 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