Skip to content

Commit 0cafd53

Browse files
committed
Fix #81011: mb_convert_encoding removes references from arrays
We need to dereference references. Closes GH-6938.
1 parent 0328ff4 commit 0cafd53

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ PHP NEWS
1515
. Fixed bug #80901 (Info leak in ftp extension). (cmb)
1616
. Fixed bug #79100 (Wrong FTP error messages). (cmb)
1717

18+
- MBString:
19+
. Fixed bug #81011 (mb_convert_encoding removes references from arrays). (cmb)
20+
1821
- ODBC:
1922
. Fixed bug #80460 (ODBC doesn't account for SQL_NO_TOTAL indicator). (cmb)
2023

ext/mbstring/mbstring.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3286,6 +3286,7 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
32863286
}
32873287
/* convert value */
32883288
ZEND_ASSERT(entry);
3289+
try_again:
32893290
switch(Z_TYPE_P(entry)) {
32903291
case IS_STRING:
32913292
cval = php_mb_convert_encoding(Z_STRVAL_P(entry), Z_STRLEN_P(entry), _to_encoding, _from_encodings, &cval_len);
@@ -3307,6 +3308,9 @@ MBSTRING_API HashTable *php_mb_convert_encoding_recursive(HashTable *input, cons
33073308
ZVAL_EMPTY_ARRAY(&entry_tmp);
33083309
}
33093310
break;
3311+
case IS_REFERENCE:
3312+
entry = Z_REFVAL_P(entry);
3313+
goto try_again;
33103314
case IS_OBJECT:
33113315
default:
33123316
if (key) {

ext/mbstring/tests/bug81011.phpt

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
--TEST--
2+
Bug #81011 (mb_convert_encoding removes references from arrays)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('mbstring')) die("skip mbstring extension not available");
6+
?>
7+
--FILE--
8+
<?php
9+
$array = [
10+
'ads' => [
11+
123 => ['name' => 'this', 'id' => 444],
12+
234 => ['name' => 'that', 'id' => 555],
13+
],
14+
'other' => ['one', 'two']
15+
];
16+
17+
// we modify array elements using reference
18+
foreach( $array['ads'] as &$ad ){
19+
$ad['premium'] = (int)($ad['id'] == 555);
20+
}
21+
22+
var_dump($array);
23+
var_dump(mb_convert_encoding($array, 'UTF-8', 'UTF-8'));
24+
?>
25+
--EXPECT--
26+
array(2) {
27+
["ads"]=>
28+
array(2) {
29+
[123]=>
30+
array(3) {
31+
["name"]=>
32+
string(4) "this"
33+
["id"]=>
34+
int(444)
35+
["premium"]=>
36+
int(0)
37+
}
38+
[234]=>
39+
&array(3) {
40+
["name"]=>
41+
string(4) "that"
42+
["id"]=>
43+
int(555)
44+
["premium"]=>
45+
int(1)
46+
}
47+
}
48+
["other"]=>
49+
array(2) {
50+
[0]=>
51+
string(3) "one"
52+
[1]=>
53+
string(3) "two"
54+
}
55+
}
56+
array(2) {
57+
["ads"]=>
58+
array(2) {
59+
[123]=>
60+
array(3) {
61+
["name"]=>
62+
string(4) "this"
63+
["id"]=>
64+
int(444)
65+
["premium"]=>
66+
int(0)
67+
}
68+
[234]=>
69+
array(3) {
70+
["name"]=>
71+
string(4) "that"
72+
["id"]=>
73+
int(555)
74+
["premium"]=>
75+
int(1)
76+
}
77+
}
78+
["other"]=>
79+
array(2) {
80+
[0]=>
81+
string(3) "one"
82+
[1]=>
83+
string(3) "two"
84+
}
85+
}

0 commit comments

Comments
 (0)