diff --git a/NEWS b/NEWS index 79df915b5bb..519622378e4 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ PHP NEWS - BCMath: . Fixed bug #44995 (bcpowmod() fails if scale != 0). (cmb) + . Fixed bug #54598 (bcpowmod() may return 1 if modulus is 1). (okano1220, cmb) - CLI server: . Fixed bug #70470 (Built-in server truncates headers spanning over TCP diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index 72a838a3646..84a7321ea7a 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -75,17 +75,24 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) /* Do the calculation. */ rscale = MAX(scale, base->n_scale); - while ( !bc_is_zero(exponent) ) + if ( !bc_compare(mod, BCG(_one_)) ) { - (void) bc_divmod (exponent, BCG(_two_), &exponent, &parity, 0); - if ( !bc_is_zero(parity) ) + temp = bc_new_num (1, scale); + } + else + { + while ( !bc_is_zero(exponent) ) { - bc_multiply (temp, power, &temp, rscale); - (void) bc_modulo (temp, mod, &temp, scale); - } + (void) bc_divmod (exponent, BCG(_two_), &exponent, &parity, 0); + if ( !bc_is_zero(parity) ) + { + bc_multiply (temp, power, &temp, rscale); + (void) bc_modulo (temp, mod, &temp, scale); + } - bc_multiply (power, power, &power, rscale); - (void) bc_modulo (power, mod, &power, scale); + bc_multiply (power, power, &power, rscale); + (void) bc_modulo (power, mod, &power, scale); + } } /* Assign the value. */ diff --git a/ext/bcmath/tests/bug54598.phpt b/ext/bcmath/tests/bug54598.phpt new file mode 100644 index 00000000000..6ccd61a2d02 --- /dev/null +++ b/ext/bcmath/tests/bug54598.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #54598 (bcpowmod() may return 1 if modulus is 1) +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +string(1) "0" +string(5) "0.000" +===DONE===