From 9afcf203de37bdc48f504d31c0eab61fa3fff1f7 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 20 Jul 2022 14:04:50 +0200 Subject: [PATCH 1/2] Fix GH-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. --- ext/mbstring/mbstring.c | 27 +++++++++++++-------------- ext/mbstring/tests/gh9008.phpt | 24 ++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 ext/mbstring/tests/gh9008.phpt diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 81863d1a6eda0..d9e19337c7131 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2694,6 +2694,13 @@ PHP_FUNCTION(mb_strtolower) } /* }}} */ +static mbfl_encoding **duplicate_elist(const mbfl_encoding **elist, size_t size) +{ + mbfl_encoding **new_elist = safe_emalloc(size, sizeof(mbfl_encoding*), 0); + memcpy(new_elist, elist, size * sizeof(mbfl_encoding*)); + return new_elist; +} + /* {{{ Encodings of the given string is returned (as a string) */ PHP_FUNCTION(mb_detect_encoding) { @@ -2707,7 +2714,6 @@ PHP_FUNCTION(mb_detect_encoding) const mbfl_encoding *ret; const mbfl_encoding **elist; size_t size; - bool free_elist; ZEND_PARSE_PARAMETERS_START(1, 3) Z_PARAM_STRING(str, str_len) @@ -2721,16 +2727,13 @@ PHP_FUNCTION(mb_detect_encoding) if (FAILURE == php_mb_parse_encoding_array(encoding_ht, &elist, &size, 2)) { RETURN_THROWS(); } - free_elist = 1; } else if (encoding_str) { 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)) { RETURN_THROWS(); } - free_elist = 1; } else { - elist = MBSTRG(current_detect_order_list); + elist = duplicate_elist(MBSTRG(current_detect_order_list), MBSTRG(current_detect_order_list_size)); size = MBSTRG(current_detect_order_list_size); - free_elist = 0; } if (size == 0) { @@ -2739,12 +2742,10 @@ PHP_FUNCTION(mb_detect_encoding) RETURN_THROWS(); } - if (free_elist) { - remove_non_encodings_from_elist(elist, &size); - if (size == 0) { - efree(ZEND_VOIDP(elist)); - RETURN_FALSE; - } + remove_non_encodings_from_elist(elist, &size); + if (size == 0) { + efree(ZEND_VOIDP(elist)); + RETURN_FALSE; } if (ZEND_NUM_ARGS() < 3) { @@ -2761,9 +2762,7 @@ PHP_FUNCTION(mb_detect_encoding) ret = mbfl_identify_encoding(&string, elist, size, strict); } - if (free_elist) { - efree(ZEND_VOIDP(elist)); - } + efree(ZEND_VOIDP(elist)); if (ret == NULL) { RETURN_FALSE; diff --git a/ext/mbstring/tests/gh9008.phpt b/ext/mbstring/tests/gh9008.phpt new file mode 100644 index 0000000000000..d1d2fd4d1f972 --- /dev/null +++ b/ext/mbstring/tests/gh9008.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-9008 (mb_detect_encoding(): wrong results with null $encodings) +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +string(5) "ASCII" +string(5) "ASCII" From 0b82e2231a440d8002eaf68fd7373c7878172e36 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Wed, 20 Jul 2022 14:33:57 +0200 Subject: [PATCH 2/2] Proper const handling --- ext/mbstring/mbstring.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index d9e19337c7131..40b8acc65fa23 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -2694,10 +2694,10 @@ PHP_FUNCTION(mb_strtolower) } /* }}} */ -static mbfl_encoding **duplicate_elist(const mbfl_encoding **elist, size_t size) +static const mbfl_encoding **duplicate_elist(const mbfl_encoding **elist, size_t size) { - mbfl_encoding **new_elist = safe_emalloc(size, sizeof(mbfl_encoding*), 0); - memcpy(new_elist, elist, size * sizeof(mbfl_encoding*)); + const mbfl_encoding **new_elist = safe_emalloc(size, sizeof(mbfl_encoding*), 0); + memcpy(ZEND_VOIDP(new_elist), elist, size * sizeof(mbfl_encoding*)); return new_elist; }