diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | ext/bcmath/libbcmath/src/raisemod.c | 22 | ||||
-rw-r--r-- | ext/bcmath/tests/bug75178.phpt | 18 |
3 files changed, 34 insertions, 7 deletions
@@ -9,6 +9,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) + . Fixed bug #75178 (bcpowmod() misbehaves for non-integer base or modulus). (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 84a7321ea7..84788b4770 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -45,7 +45,7 @@ int bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) { - bc_num power, exponent, parity, temp; + bc_num power, exponent, modulus, parity, temp; int rscale; /* Check for correct numbers. */ @@ -55,12 +55,16 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) /* Set initial values. */ power = bc_copy_num (base); exponent = bc_copy_num (expo); + modulus = bc_copy_num (mod); temp = bc_copy_num (BCG(_one_)); bc_init_num(&parity); /* Check the base for scale digits. */ - if (base->n_scale != 0) + if (power->n_scale != 0) + { bc_rt_warn ("non-zero scale in base"); + bc_divide (power, BCG(_one_), &power, 0); /*truncate */ + } /* Check the exponent for scale digits. */ if (exponent->n_scale != 0) @@ -70,12 +74,15 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) } /* Check the modulus for scale digits. */ - if (mod->n_scale != 0) + if (modulus->n_scale != 0) + { bc_rt_warn ("non-zero scale in modulus"); + bc_divide (modulus, BCG(_one_), &modulus, 0); /*truncate */ + } /* Do the calculation. */ - rscale = MAX(scale, base->n_scale); - if ( !bc_compare(mod, BCG(_one_)) ) + rscale = MAX(scale, power->n_scale); + if ( !bc_compare(modulus, BCG(_one_)) ) { temp = bc_new_num (1, scale); } @@ -87,17 +94,18 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) if ( !bc_is_zero(parity) ) { bc_multiply (temp, power, &temp, rscale); - (void) bc_modulo (temp, mod, &temp, scale); + (void) bc_modulo (temp, modulus, &temp, scale); } bc_multiply (power, power, &power, rscale); - (void) bc_modulo (power, mod, &power, scale); + (void) bc_modulo (power, modulus, &power, scale); } } /* Assign the value. */ bc_free_num (&power); bc_free_num (&exponent); + bc_free_num (&modulus); bc_free_num (result); bc_free_num (&parity); *result = temp; diff --git a/ext/bcmath/tests/bug75178.phpt b/ext/bcmath/tests/bug75178.phpt new file mode 100644 index 0000000000..4e25256648 --- /dev/null +++ b/ext/bcmath/tests/bug75178.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #75178 (bcpowmod() misbehaves for non-integer base or modulus) +--SKIPIF-- +<?php +if (!extension_loaded('bcmath')) die('skip bcmath extension is not available'); +?> +--FILE-- +<?php +var_dump(bcpowmod('4.1', '4', '3', 3)); +var_dump(bcpowmod('4', '4', '3.1', 3)); +?> +===DONE=== +--EXPECT-- +bc math warning: non-zero scale in base +string(5) "1.000" +bc math warning: non-zero scale in modulus +string(5) "1.000" +===DONE=== |