Merge branch 'PHP-8.3' into PHP-8.4

* PHP-8.3:
  Fix GH-16261: Reference invariant broken in mb_convert_variables()
This commit is contained in:
Niels Dossche 2024-10-07 17:49:56 +02:00
commit 07e418abfb
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
3 changed files with 64 additions and 1 deletions

4
NEWS
View file

@ -77,6 +77,10 @@ PHP NEWS
. Fix GH-16136 (Memory leak in php_ldap_do_modify() when entry is not a . Fix GH-16136 (Memory leak in php_ldap_do_modify() when entry is not a
proper dictionary). (Girgias) proper dictionary). (Girgias)
- MBString:
. Fixed bug GH-16261 (Reference invariant broken in mb_convert_variables()).
(nielsdos)
- Opcache: - Opcache:
. Fixed bug GH-16009 (Segmentation fault with frameless functions and . Fixed bug GH-16009 (Segmentation fault with frameless functions and
undefined CVs). (nielsdos) undefined CVs). (nielsdos)

View file

@ -3770,7 +3770,22 @@ static bool mb_recursive_convert_variable(zval *var, const mbfl_encoding* from_e
HashTable *ht = HASH_OF(var); HashTable *ht = HASH_OF(var);
if (ht != NULL) { if (ht != NULL) {
ZEND_HASH_FOREACH_VAL_IND(ht, entry) { ZEND_HASH_FOREACH_VAL(ht, entry) {
/* Can be a typed property declaration, in which case we need to remove the reference from the source list.
* Just using ZEND_TRY_ASSIGN_STRINGL is not sufficient because that would not unwrap the reference
* and change values through references (see bug #26639). */
if (Z_TYPE_P(entry) == IS_INDIRECT) {
ZEND_ASSERT(Z_TYPE_P(var) == IS_OBJECT);
entry = Z_INDIRECT_P(entry);
if (Z_ISREF_P(entry) && Z_TYPE_P(Z_REFVAL_P(entry)) == IS_STRING) {
zend_property_info *info = zend_get_typed_property_info_for_slot(Z_OBJ_P(var), entry);
if (info) {
ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(entry), info);
}
}
}
if (mb_recursive_convert_variable(entry, from_encoding, to_encoding)) { if (mb_recursive_convert_variable(entry, from_encoding, to_encoding)) {
if (Z_REFCOUNTED_P(var)) { if (Z_REFCOUNTED_P(var)) {
Z_UNPROTECT_RECURSION_P(var); Z_UNPROTECT_RECURSION_P(var);

View file

@ -0,0 +1,44 @@
--TEST--
GH-16261 (Reference invariant broken in mb_convert_variables())
--EXTENSIONS--
mbstring
--FILE--
<?php
class Test {
public string $x;
public string $y;
public array $z;
}
$test = new Test;
$ref = "hello";
$ref2 = "world";
$ref3 = [&$ref2];
$test->x =& $ref;
$test->z =& $ref3;
mb_convert_variables("EUC-JP", "Shift_JIS", $test);
class Test2 {
public function __construct(public string $x) {}
}
$test2 = new Test2("foo");
mb_convert_variables("EUC-JP", "Shift_JIS", $test->x);
var_dump($test, $test2);
?>
--EXPECT--
object(Test)#1 (2) {
["x"]=>
string(5) "hello"
["y"]=>
uninitialized(string)
["z"]=>
&array(1) {
[0]=>
string(5) "world"
}
}
object(Test2)#2 (1) {
["x"]=>
string(3) "foo"
}