Commit 4f83876af75 for php.net

commit 4f83876af75d43b24cf3ed567394451f42e6bca1
Author: Recep A. <44113214+recepasan@users.noreply.github.com>
Date:   Wed May 27 21:48:08 2026 +0300

    Fix out-of-bounds write in ext-bcmath bccomp() via bc_str2num()

    When a fraction is truncated to a caller-supplied scale and then re-trimmed of
    trailing zeros, str_scale was reduced but fractional_end was not, so
    bc_copy_and_toggle_bcd() copied more bytes than were reserved by
    bc_new_num_nonzeroed(). With small numbers allocated from the 256-byte stack
    arena this is a stack-based OOB write reachable via bccomp($num1, $num2,
    $scale), e.g. bccomp("1.901", "0", 2).

    Keep fractional_end in sync with str_scale so the copy length matches the
    reserved length.

    Fixes GHSA-x692-q9x7-8c3f

diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c
index bd9a44a2405..3b99065b43f 100644
--- a/ext/bcmath/libbcmath/src/str2num.c
+++ b/ext/bcmath/libbcmath/src/str2num.c
@@ -181,6 +181,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz
 			if (str_scale > 0) {
 				const char *fractional_new_end = bc_skip_zero_reverse(fractional_end, fractional_ptr);
 				str_scale -= fractional_end - fractional_new_end; /* fractional_end >= fractional_new_end */
+				fractional_end = fractional_new_end;
 			}
 		}
 	} else {
diff --git a/ext/bcmath/tests/GHSA-x692-q9x7-8c3f.phpt b/ext/bcmath/tests/GHSA-x692-q9x7-8c3f.phpt
new file mode 100644
index 00000000000..b735958bd07
--- /dev/null
+++ b/ext/bcmath/tests/GHSA-x692-q9x7-8c3f.phpt
@@ -0,0 +1,13 @@
+--TEST--
+GHSA-x692-q9x7-8c3f: bccomp() out-of-bounds write
+--CREDITS--
+Recep Asan (recepasan)
+--FILE--
+<?php
+
+$n = '1.' . '9' . str_repeat('0', 300) . '1';
+var_dump(bccomp($n, '0', 300));
+
+?>
+--EXPECT--
+int(1)