From b7524bbf555e1b6b2b7a29e6b278f13693e23525 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 4 Feb 2025 00:41:34 +0100 Subject: [PATCH 1/3] Fix GH-17503: Undefined float conversion in mb_convert_variables Conversion of floating point to integer values is undefined if the integral part of the float value cannot be represented by the integer type. We need to cater to that explicitly (in a manner similar to `zend_dval_to_lval_cap()`). --- ext/mbstring/mbstring.c | 3 ++- ext/mbstring/tests/gh17503.phpt | 11 +++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 ext/mbstring/tests/gh17503.phpt diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 2da957454a902..87c3d3e681437 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3092,7 +3092,8 @@ try_next_encoding:; } for (size_t i = 0; i < length; i++) { - array[i].demerits *= array[i].multiplier; + float demerits = array[i].demerits * array[i].multiplier; + array[i].demerits = demerits < (float) UINT64_MAX ? (uint64_t) demerits : UINT64_MAX; } return length; diff --git a/ext/mbstring/tests/gh17503.phpt b/ext/mbstring/tests/gh17503.phpt new file mode 100644 index 0000000000000..92a2cf39cb10f --- /dev/null +++ b/ext/mbstring/tests/gh17503.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-17503 (Undefined float conversion in mb_convert_variables) +--EXTENSIONS-- +mbstring +--FILE-- +"); +var_dump(mb_convert_variables("ASCII", ["UTF-8", "UTF-16"], $a)); +?> +--EXPECT-- +string(5) "UTF-8" From 8ce18c44ff934d873396c20a87af77d31880744d Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 4 Feb 2025 12:11:38 +0100 Subject: [PATCH 2/3] Use double instead of float --- ext/mbstring/mbstring.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 87c3d3e681437..3a085fbd2ce12 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3092,8 +3092,8 @@ try_next_encoding:; } for (size_t i = 0; i < length; i++) { - float demerits = array[i].demerits * array[i].multiplier; - array[i].demerits = demerits < (float) UINT64_MAX ? (uint64_t) demerits : UINT64_MAX; + double demerits = array[i].demerits * array[i].multiplier; + array[i].demerits = demerits < (double) UINT64_MAX ? (uint64_t) demerits : UINT64_MAX; } return length; From 1ddbc93afd34c4564934f2f7e790bc05b6b68c84 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 4 Feb 2025 12:13:24 +0100 Subject: [PATCH 3/3] double multiplication --- 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 3a085fbd2ce12..dbf012174c494 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -3092,7 +3092,7 @@ try_next_encoding:; } for (size_t i = 0; i < length; i++) { - double demerits = array[i].demerits * array[i].multiplier; + double demerits = array[i].demerits * (double) array[i].multiplier; array[i].demerits = demerits < (double) UINT64_MAX ? (uint64_t) demerits : UINT64_MAX; }