diff --git a/ext/bcmath/libbcmath/src/div.c b/ext/bcmath/libbcmath/src/div.c index e9377fcfc4279..ce9ae1e1dd792 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 0000000000000..c5be97bdaa884 --- /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"