Fixed bug #54598 (bcpowmod() may return 1 if modulus is 1)
authorChristoph M. Becker <cmbecker69@gmx.de>
Wed, 6 Sep 2017 22:30:05 +0000 (00:30 +0200)
committerChristoph M. Becker <cmbecker69@gmx.de>
Wed, 6 Sep 2017 22:30:05 +0000 (00:30 +0200)
`x mod 1` is always zero; we have to take the scale into account,
though.

NEWS
ext/bcmath/libbcmath/src/raisemod.c
ext/bcmath/tests/bug54598.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 377f4d154067b026ea25402cf4100edd41df8a93..7fb0cb106576b909364aa46621ad51eeb17aab42 100644 (file)
--- 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
index 72a838a3646286117ec2d0ee0af40f3852a61222..84a7321ea7a6b769885b902924de3ca2ffef19c8 100644 (file)
@@ -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 (file)
index 0000000..6ccd61a
--- /dev/null
@@ -0,0 +1,16 @@
+--TEST--
+Bug #54598 (bcpowmod() may return 1 if modulus is 1)
+--SKIPIF--
+<?php
+if (!extension_loaded('bcmath')) die('skip bcmath extension is not available');
+?>
+--FILE--
+<?php
+var_dump(bcpowmod(5, 0, 1));
+var_dump(bcpowmod(5, 0, 1, 3));
+?>
+===DONE===
+--EXPECT--
+string(1) "0"
+string(5) "0.000"
+===DONE===