Commit 979c827cdc3 for php.net
commit 979c827cdc393a164a2fbfeb524ec76ada3ef78c
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Tue Aug 4 22:03:22 2026 -0400
Clamp scale in bc_is_zero_for_scale to n_scale
Number::compare() may request a scale greater than the stored scale of a
zero result when the opposite operand has a larger scale. The helper then
walked past the shorter digit buffer.
Clamp the requested scale to the digits stored in the number.
Closes GH-23185
diff --git a/NEWS b/NEWS
index ab8e20c7507..1cc265f02e8 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.4.26
+- BCMath:
+ . Fixed out-of-bounds read in bc_is_zero_for_scale() when scale exceeds
+ n_scale. (Ilia Alshanetsky)
+
- Core:
. Fixed bug GH-15375 (Nested "yield from" skips items after a valid() or
next() call on the inner generator). (iliaal)
diff --git a/ext/bcmath/libbcmath/src/zero.c b/ext/bcmath/libbcmath/src/zero.c
index 550ea97df67..e488069bae1 100644
--- a/ext/bcmath/libbcmath/src/zero.c
+++ b/ext/bcmath/libbcmath/src/zero.c
@@ -45,6 +45,10 @@ bool bc_is_zero_for_scale(bc_num num, size_t scale)
return true;
}
+ if (scale > num->n_scale) {
+ scale = num->n_scale;
+ }
+
/* Initialize */
count = num->n_len + scale;
nptr = num->n_value;
diff --git a/ext/bcmath/tests/bc_is_zero_for_scale_clamp.phpt b/ext/bcmath/tests/bc_is_zero_for_scale_clamp.phpt
new file mode 100644
index 00000000000..887fabb9291
--- /dev/null
+++ b/ext/bcmath/tests/bc_is_zero_for_scale_clamp.phpt
@@ -0,0 +1,12 @@
+--TEST--
+bc_is_zero_for_scale clamps scale to n_scale (Number::compare opposite signs)
+--EXTENSIONS--
+bcmath
+--FILE--
+<?php
+$shortZero = (new BcMath\Number('1.0'))->sub('1.0');
+$longNegative = new BcMath\Number('-0.' . str_repeat('0', 64) . '1');
+var_dump($shortZero->compare($longNegative, 64));
+?>
+--EXPECT--
+int(0)