From 5657d0a6262b6d534bc9f48740e1f84d9c852cad Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Tue, 18 Nov 2025 17:15:06 +0100 Subject: [PATCH 1/8] mbstring: fix missing copying of detect_order_list to current_detect_order_list on ini_set('mbstring.detect_order', string) --- ext/mbstring/mbstring.c | 3 ++ .../tests/mb_detect_order_with_ini_set.phpt | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 ext/mbstring/tests/mb_detect_order_with_ini_set.phpt diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 7fda240b7051a..21b1a14476adb 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -718,6 +718,9 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) } MBSTRG(detect_order_list) = list; MBSTRG(detect_order_list_size) = size; + + php_mb_populate_current_detect_order_list(); + return SUCCESS; } /* }}} */ diff --git a/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt b/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt new file mode 100644 index 0000000000000..edda1c4b0ca71 --- /dev/null +++ b/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test mb_detect_order() function : ini set changes order +--EXTENSIONS-- +mbstring +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + string(5) "UTF-8" + [1]=> + string(10) "ISO-8859-1" + [2]=> + string(5) "ASCII" +} +array(1) { + [0]=> + string(5) "UTF-8" +} From 316fe83dd113893d84cff20d3e65d21b69129851 Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Tue, 18 Nov 2025 17:15:27 +0100 Subject: [PATCH 2/8] mbstring: fix memory leak at updating current_detect_order_list --- ext/mbstring/mbstring.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 21b1a14476adb..72a8dd7392860 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -5984,6 +5984,11 @@ static void php_mb_populate_current_detect_order_list(void) entry[i] = mbfl_no2encoding(src[i]); } } + + if (MBSTRG(current_detect_order_list) != NULL) { + efree(ZEND_VOIDP(MBSTRG(current_detect_order_list))); + } + MBSTRG(current_detect_order_list) = entry; MBSTRG(current_detect_order_list_size) = nentries; } From 52ca6bfecea99022c08e17fac7b3ec5b8c89e1c6 Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Tue, 18 Nov 2025 21:24:51 +0100 Subject: [PATCH 3/8] Add preloaded ini config --- .../tests/mb_detect_order_with_ini_set.phpt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt b/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt index edda1c4b0ca71..2e43b86a15605 100644 --- a/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt +++ b/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt @@ -2,9 +2,13 @@ Test mb_detect_order() function : ini set changes order --EXTENSIONS-- mbstring +--INI-- +mbstring.detect_order=UTF-8,ISO-8859-15,ISO-8859-1,ASCII --FILE-- --EXPECT-- +array(4) { + [0]=> + string(5) "UTF-8" + [1]=> + string(11) "ISO-8859-15" + [2]=> + string(10) "ISO-8859-1" + [3]=> + string(5) "ASCII" +} array(3) { [0]=> string(5) "UTF-8" From 704f1fb9dd2892febffb78c8f06c401ba7056469 Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Tue, 18 Nov 2025 21:25:28 +0100 Subject: [PATCH 4/8] fix php_mb_populate_current_detect_order_list is called twice --- ext/mbstring/mbstring.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 72a8dd7392860..8f94e50ddc861 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -719,7 +719,9 @@ static PHP_INI_MH(OnUpdate_mbstring_detect_order) MBSTRG(detect_order_list) = list; MBSTRG(detect_order_list_size) = size; - php_mb_populate_current_detect_order_list(); + if (stage == PHP_INI_STAGE_RUNTIME) { + php_mb_populate_current_detect_order_list(); + } return SUCCESS; } From f199ce70825a58e5c266bb0df27156fd76b3e102 Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Tue, 18 Nov 2025 22:47:37 +0100 Subject: [PATCH 5/8] replace efree with pefree --- ext/mbstring/mbstring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 8f94e50ddc861..16c6f68835f2f 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -5988,7 +5988,7 @@ static void php_mb_populate_current_detect_order_list(void) } if (MBSTRG(current_detect_order_list) != NULL) { - efree(ZEND_VOIDP(MBSTRG(current_detect_order_list))); + pefree(ZEND_VOIDP(MBSTRG(current_detect_order_list)), 1); } MBSTRG(current_detect_order_list) = entry; From 4001ff99adec0b162ca85d9e1d1499b393929946 Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Tue, 18 Nov 2025 23:05:26 +0100 Subject: [PATCH 6/8] add more testcases for setting empty mbstring.detect_order values --- .../tests/mb_detect_order_with_ini_set.phpt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt b/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt index 2e43b86a15605..ba59f3388b85e 100644 --- a/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt +++ b/ext/mbstring/tests/mb_detect_order_with_ini_set.phpt @@ -17,6 +17,14 @@ ini_set('mbstring.detect_order', 'UTF-8'); var_dump( mb_detect_order()); +ini_set('mbstring.detect_order', NULL); + +var_dump( mb_detect_order()); + +ini_set('mbstring.detect_order', ''); + +var_dump( mb_detect_order()); + ?> --EXPECT-- array(4) { @@ -41,3 +49,12 @@ array(1) { [0]=> string(5) "UTF-8" } +array(1) { + [0]=> + string(5) "UTF-8" +} +array(1) { + [0]=> + string(5) "UTF-8" +} + From 5c2f5ce1fa1404d49d95ff8639c2fae228822499 Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Tue, 18 Nov 2025 23:06:30 +0100 Subject: [PATCH 7/8] Revert "replace efree with pefree" This reverts commit b82312a7a19b570047ed53dc5fc8c67c9f60b709. --- ext/mbstring/mbstring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 16c6f68835f2f..8f94e50ddc861 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -5988,7 +5988,7 @@ static void php_mb_populate_current_detect_order_list(void) } if (MBSTRG(current_detect_order_list) != NULL) { - pefree(ZEND_VOIDP(MBSTRG(current_detect_order_list)), 1); + efree(ZEND_VOIDP(MBSTRG(current_detect_order_list))); } MBSTRG(current_detect_order_list) = entry; From 557f2d373f1fcdf20574054d6ef3127ac759d62f Mon Sep 17 00:00:00 2001 From: Tobias Vorwachs Date: Mon, 1 Dec 2025 11:38:21 +0100 Subject: [PATCH 8/8] mbstring: updating NEWS and UPGRADING for changed behavior of ini_set() with mbstring.detect_order --- NEWS | 4 ++++ UPGRADING | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/NEWS b/NEWS index 604945a77c701..18d931bccded7 100644 --- a/NEWS +++ b/NEWS @@ -20,6 +20,10 @@ PHP NEWS . Fixed bug GH-20483 (ASAN stack overflow with fiber.stack_size INI small value). (David Carlier) +- Mbstring: + . ini_set() with mbstring.detect_order changes the order of mb_detect_order + as intended, since mbstring.detect_order is an INI_ALL setting. (tobee94) + - Opcache: . Fixed bug GH-20051 (apache2 shutdowns when restart is requested during preloading). (Arnaud, welcomycozyhom) diff --git a/UPGRADING b/UPGRADING index 1e84b8beee97a..7f0fcaf8943a8 100644 --- a/UPGRADING +++ b/UPGRADING @@ -98,6 +98,13 @@ PHP 8.6 UPGRADE NOTES When used along with ZEND_JIT_DEBUG_TRACE_EXIT_INFO, the source of exit points is printed in exit info output, in debug builds. +- Mbstring: + . The mbstring.detect_order INI directive now updates the internal detection + order when changed at runtime via ini_set(). Previously, runtime changes + using ini_set() did not take effect for mb_detect_order(). Setting the + directive to NULL or an empty string at runtime now leaves the previously + configured detection order unchanged. + ======================================== 12. Windows Support ========================================