From ef036090d986beab2690fa400084411dbefad57e Mon Sep 17 00:00:00 2001 From: Saki Takamachi Date: Fri, 27 Dec 2024 21:36:26 +0900 Subject: [PATCH] Fixed GH-17275: Fixed the calculation logic of dividend scale (#17279) Fixes #17275 Closes #17279 --- NEWS | 2 ++ ext/bcmath/libbcmath/src/div.c | 14 ++++++++++---- ext/bcmath/tests/gh17275.phpt | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 ext/bcmath/tests/gh17275.phpt diff --git a/NEWS b/NEWS index 898dda52a4d..d2222b5123c 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,8 @@ PHP NEWS (Saki Takamachi) . Fixed bug GH-17064 (Correctly round rounding mode with zero edge case). (Saki Takamachi) + . Fixed bug GH-17275 (Fixed the calculation logic of dividend scale). + (Saki Takamachi) - Core: . Fixed bug OSS-Fuzz #382922236 (Duplicate dynamic properties in hooked object diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index e9377fcfc42..ce9ae1e1dd7 100644 --- a/ext/bcmath/libbcmath/src/div.c +++ b/ext/bcmath/libbcmath/src/div.c @@ -427,6 +427,9 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) return true; } + /* Length of numerator data that can be read */ + size_t numerator_readable_len = numeratorend - numeratorptr + 1; + /* set scale to numerator */ if (numerator_scale > scale) { size_t scale_diff = numerator_scale - scale; @@ -434,7 +437,13 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) numerator_bottom_extension -= scale_diff; } else { numerator_bottom_extension = 0; - numeratorend -= scale_diff > numerator_top_extension ? scale_diff - numerator_top_extension : 0; + if (EXPECTED(numerator_readable_len > scale_diff)) { + numerator_readable_len -= scale_diff; + numeratorend -= scale_diff; + } else { + numerator_readable_len = 0; + numeratorend = numeratorptr; + } } numerator_top_extension = MIN(numerator_top_extension, scale); } else { @@ -442,9 +451,6 @@ bool bc_divide(bc_num numerator, bc_num divisor, bc_num *quot, size_t scale) } numerator_scale = scale; - /* Length of numerator data that can be read */ - size_t numerator_readable_len = numeratorend - numeratorptr + 1; - if (divisor_len > numerator_readable_len + numerator_bottom_extension) { *quot = bc_copy_num(BCG(_zero_)); return true; diff --git a/ext/bcmath/tests/gh17275.phpt b/ext/bcmath/tests/gh17275.phpt new file mode 100644 index 00000000000..c5be97bdaa8 --- /dev/null +++ b/ext/bcmath/tests/gh17275.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-17275 Incorrect result of bcdiv function +--EXTENSIONS-- +bcmath +--FILE-- + +--EXPECT-- +string(10) "0.00000390" +string(11) "0.000003909"