Skip to content

Commit 9afcf20

Browse files
committed
Fix phpGH-9008: mb_detect_encoding(): wrong results with null $encodings
Passing `null` to `$encodings` is supposed to behave like passing the result of `mb_detect_order()`. Therefore, we need to remove the non- encodings from the `elist` in this case as well. Thus, we duplicate the global `elist`, so we can modify it.
1 parent 9af3327 commit 9afcf20

File tree

2 files changed

+37
-14
lines changed

2 files changed

+37
-14
lines changed

ext/mbstring/mbstring.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2694,6 +2694,13 @@ PHP_FUNCTION(mb_strtolower)
26942694
}
26952695
/* }}} */
26962696

2697+
static mbfl_encoding **duplicate_elist(const mbfl_encoding **elist, size_t size)
2698+
{
2699+
mbfl_encoding **new_elist = safe_emalloc(size, sizeof(mbfl_encoding*), 0);
2700+
memcpy(new_elist, elist, size * sizeof(mbfl_encoding*));
2701+
return new_elist;
2702+
}
2703+
26972704
/* {{{ Encodings of the given string is returned (as a string) */
26982705
PHP_FUNCTION(mb_detect_encoding)
26992706
{
@@ -2707,7 +2714,6 @@ PHP_FUNCTION(mb_detect_encoding)
27072714
const mbfl_encoding *ret;
27082715
const mbfl_encoding **elist;
27092716
size_t size;
2710-
bool free_elist;
27112717

27122718
ZEND_PARSE_PARAMETERS_START(1, 3)
27132719
Z_PARAM_STRING(str, str_len)
@@ -2721,16 +2727,13 @@ PHP_FUNCTION(mb_detect_encoding)
27212727
if (FAILURE == php_mb_parse_encoding_array(encoding_ht, &elist, &size, 2)) {
27222728
RETURN_THROWS();
27232729
}
2724-
free_elist = 1;
27252730
} else if (encoding_str) {
27262731
if (FAILURE == php_mb_parse_encoding_list(ZSTR_VAL(encoding_str), ZSTR_LEN(encoding_str), &elist, &size, /* persistent */ 0, /* arg_num */ 2, /* allow_pass_encoding */ 0)) {
27272732
RETURN_THROWS();
27282733
}
2729-
free_elist = 1;
27302734
} else {
2731-
elist = MBSTRG(current_detect_order_list);
2735+
elist = duplicate_elist(MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size));
27322736
size = MBSTRG(current_detect_order_list_size);
2733-
free_elist = 0;
27342737
}
27352738

27362739
if (size == 0) {
@@ -2739,12 +2742,10 @@ PHP_FUNCTION(mb_detect_encoding)
27392742
RETURN_THROWS();
27402743
}
27412744

2742-
if (free_elist) {
2743-
remove_non_encodings_from_elist(elist, &size);
2744-
if (size == 0) {
2745-
efree(ZEND_VOIDP(elist));
2746-
RETURN_FALSE;
2747-
}
2745+
remove_non_encodings_from_elist(elist, &size);
2746+
if (size == 0) {
2747+
efree(ZEND_VOIDP(elist));
2748+
RETURN_FALSE;
27482749
}
27492750

27502751
if (ZEND_NUM_ARGS() < 3) {
@@ -2761,9 +2762,7 @@ PHP_FUNCTION(mb_detect_encoding)
27612762
ret = mbfl_identify_encoding(&string, elist, size, strict);
27622763
}
27632764

2764-
if (free_elist) {
2765-
efree(ZEND_VOIDP(elist));
2766-
}
2765+
efree(ZEND_VOIDP(elist));
27672766

27682767
if (ret == NULL) {
27692768
RETURN_FALSE;

ext/mbstring/tests/gh9008.phpt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GH-9008 (mb_detect_encoding(): wrong results with null $encodings)
3+
--EXTENSIONS--
4+
mbstring
5+
--FILE--
6+
<?php
7+
$string = "<?php
8+
9+
function test()
10+
{
11+
12+
}
13+
";
14+
15+
mb_detect_order(["ASCII", "UUENCODE"]);
16+
17+
var_dump(
18+
mb_detect_encoding($string, null, true),
19+
mb_detect_encoding($string, mb_detect_order(), true),
20+
);
21+
?>
22+
--EXPECT--
23+
string(5) "ASCII"
24+
string(5) "ASCII"

0 commit comments

Comments
 (0)