]> granicus.if.org Git - php/commitdiff
Promote some warnings in BCMath to Errors
authorGeorge Peter Banyard <girgias@php.net>
Fri, 11 Sep 2020 15:40:06 +0000 (17:40 +0200)
committerGeorge Peter Banyard <girgias@php.net>
Fri, 11 Sep 2020 15:40:06 +0000 (17:40 +0200)
Also do a bit of refactoring at the same time.

Closes GH-6105

18 files changed:
ext/bcmath/bcmath.c
ext/bcmath/config.m4
ext/bcmath/config.w32
ext/bcmath/libbcmath/src/bcmath.h
ext/bcmath/libbcmath/src/init.c
ext/bcmath/libbcmath/src/num2str.c
ext/bcmath/libbcmath/src/outofmem.c [deleted file]
ext/bcmath/libbcmath/src/raise.c
ext/bcmath/libbcmath/src/raisemod.c
ext/bcmath/tests/bcpow_error1.phpt
ext/bcmath/tests/bcpow_error2.phpt
ext/bcmath/tests/bcpowmod.phpt
ext/bcmath/tests/bcpowmod_negative_exponent.phpt
ext/bcmath/tests/bcpowmod_zero_modulus.phpt
ext/bcmath/tests/bcsqrt_error1.phpt
ext/bcmath/tests/bug72093.phpt
ext/bcmath/tests/bug75178.phpt
ext/bcmath/tests/bug78878.phpt

index 17f28f1781a32f83a0991c1d92e4bd1f6e121843..f20dda534fd26e37df1891fc3267916cfaa33863 100644 (file)
@@ -393,16 +393,8 @@ PHP_FUNCTION(bcpowmod)
        php_str2num(&second, ZSTR_VAL(right));
        php_str2num(&mod, ZSTR_VAL(modulus));
 
-       switch (bc_raisemod(first, second, mod, &result, scale)) {
-               case 0:
-                       RETVAL_STR(bc_num2str_ex(result, scale));
-                       break;
-               case -1:
-                       zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
-                       break;
-               case -2:
-                       zend_argument_value_error(2, "must be greater than 0");
-                       break;
+       if (bc_raisemod(first, second, mod, &result, scale) == SUCCESS) {
+               RETVAL_STR(bc_num2str_ex(result, scale));
        }
 
        bc_free_num(&first);
@@ -481,7 +473,7 @@ PHP_FUNCTION(bcsqrt)
        if (bc_sqrt (&result, scale) != 0) {
                RETVAL_STR(bc_num2str_ex(result, scale));
        } else {
-               zend_value_error("Square root of negative number");
+               zend_argument_value_error(1, "must be greater than or equal to 0");
        }
 
        bc_free_num(&result);
index 2877a7d4adab01b352904206a9ec67fcda8624ea..ee9fa3f3c9e1cb831a9127933ce2885218388dfa 100644 (file)
@@ -5,7 +5,7 @@ PHP_ARG_ENABLE([bcmath],
 
 if test "$PHP_BCMATH" != "no"; then
   PHP_NEW_EXTENSION(bcmath, bcmath.c \
-libbcmath/src/add.c libbcmath/src/div.c libbcmath/src/init.c libbcmath/src/neg.c libbcmath/src/outofmem.c libbcmath/src/raisemod.c libbcmath/src/sub.c \
+libbcmath/src/add.c libbcmath/src/div.c libbcmath/src/init.c libbcmath/src/neg.c libbcmath/src/raisemod.c libbcmath/src/sub.c \
 libbcmath/src/compare.c libbcmath/src/divmod.c libbcmath/src/int2num.c libbcmath/src/num2long.c libbcmath/src/output.c libbcmath/src/recmul.c \
 libbcmath/src/sqrt.c libbcmath/src/zero.c libbcmath/src/debug.c libbcmath/src/doaddsub.c libbcmath/src/nearzero.c libbcmath/src/num2str.c libbcmath/src/raise.c \
 libbcmath/src/rmzero.c libbcmath/src/str2num.c,
index eaf217774d31d49edd22985d998e04497e91ada7..04ffa31d58384307e6563cfa489529c08b7a7a42 100644 (file)
@@ -5,7 +5,7 @@ ARG_ENABLE("bcmath", "bc style precision math functions", "yes");
 if (PHP_BCMATH == "yes") {
        EXTENSION("bcmath", "bcmath.c", null, "-Iext/bcmath/libbcmath/src /DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
        ADD_SOURCES("ext/bcmath/libbcmath/src", "add.c div.c init.c neg.c \
-               outofmem.c raisemod.c sub.c compare.c divmod.c int2num.c \
+               raisemod.c sub.c compare.c divmod.c int2num.c \
                num2long.c output.c recmul.c sqrt.c zero.c debug.c doaddsub.c \
                nearzero.c num2str.c raise.c rmzero.c str2num.c", "bcmath");
 
index becba7ec3e2db74a4d8a5a7f49dd419d85ad99ef..24425544bb2f63f75a8fc5e0062a4c1b58960cb3 100644 (file)
@@ -150,9 +150,6 @@ _PROTOTYPE(void bc_out_num, (bc_num num, int o_base, void (* out_char)(int),
                             int leading_zero));
 
 /* Prototypes needed for external utility routines. */
-
-_PROTOTYPE(void bc_out_of_memory, (void));
-
 #define bc_new_num(length, scale)      _bc_new_num_ex((length), (scale), 0)
 #define bc_free_num(num)                       _bc_free_num_ex((num), 0)
 #define bc_num2str(num)                                bc_num2str_ex((num), (num->n_scale))
index 676076f89ddb069f7da5586c8368dbac480483c9..96e934b34da7683173d7289fd2ae2891e381ac31 100644 (file)
@@ -44,10 +44,6 @@ _bc_new_num_ex (length, scale, persistent)
      int length, scale, persistent;
 {
   bc_num temp;
-  /* PHP Change:  add length check */
-  if ((size_t)length+(size_t)scale > INT_MAX) {
-   zend_error(E_ERROR, "Result too long, max is %d", INT_MAX);
-  }
   /* PHP Change:  malloc() -> pemalloc(), removed free_list code */
   temp = (bc_num) safe_pemalloc (1, sizeof(bc_struct)+length, scale, persistent);
   temp->n_sign = PLUS;
index 23988c0d6c5db0573478c4241c23ba889c21c6cf..3e23158125282534f6ebd01c6955b2b1d68b1aa1 100644 (file)
@@ -55,7 +55,6 @@ zend_string
                str = zend_string_alloc(num->n_len + scale + signch + 1, 0);
        else
                str = zend_string_alloc(num->n_len + signch, 0);
-       if (str == NULL) bc_out_of_memory();
 
        /* The negative sign if needed. */
        sptr = ZSTR_VAL(str);
diff --git a/ext/bcmath/libbcmath/src/outofmem.c b/ext/bcmath/libbcmath/src/outofmem.c
deleted file mode 100644 (file)
index cb2f108..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* outofmem.c: bcmath library file. */
-/*
-    Copyright (C) 1991, 1992, 1993, 1994, 1997 Free Software Foundation, Inc.
-    Copyright (C) 2000 Philip A. Nelson
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.  (LICENSE)
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to:
-
-      The Free Software Foundation, Inc.
-      59 Temple Place, Suite 330
-      Boston, MA 02111-1307 USA.
-
-    You may contact the author by:
-       e-mail:  philnelson@acm.org
-      us-mail:  Philip A. Nelson
-                Computer Science Department, 9062
-                Western Washington University
-                Bellingham, WA 98226-9062
-
-*************************************************************************/
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdarg.h>
-#include "bcmath.h"
-#include "private.h"
-
-
-void bc_out_of_memory (void)
-{
-  zend_error(E_ERROR, "bcmath: out of memory!");
-}
index 700a50f50c085086c8f6b07116ec5c061cd10ade..2e843f179a6d6f8d7562f9740c502d519775dc27 100644 (file)
@@ -52,12 +52,18 @@ bc_raise (bc_num num1, bc_num num2, bc_num *result, int scale)
    int calcscale;
    char neg;
 
-   /* Check the exponent for scale digits and convert to a long. */
-   if (num2->n_scale != 0)
-     php_error_docref (NULL, E_WARNING, "Non-zero scale in exponent");
-   exponent = bc_num2long (num2);
-   if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0))
-       php_error_docref (NULL, E_WARNING, "Exponent too large");
+       /* Check the exponent for scale digits and convert to a long. */
+       if (num2->n_scale != 0) {
+               /* 2nd argument from PHP_FUNCTION(bcpow) */
+               zend_argument_value_error(2, "cannot have a fractional part");
+               return;
+       }
+       exponent = bc_num2long (num2);
+       if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0)) {
+               /* 2nd argument from PHP_FUNCTION(bcpow) */
+               zend_argument_value_error(2, "is too large");
+               return;
+       }
 
    /* Special case if exponent is a zero. */
    if (exponent == 0)
index 46dfd7a8a863a1043676be9dc2cd14f85adc32a0..bb0d16f6f0a5586bac35e5c914f00fecbd3bd4bc 100644 (file)
 #include <stdarg.h>
 #include "bcmath.h"
 #include "private.h"
+#include "zend_exceptions.h"
 
-
-/* Truncate a number to zero scale.  To avoid sharing issues (refcount and
-   shared n_value) the number is copied, this copy is truncated, and the
-   original number is "freed". */
-
-static void
-_bc_truncate (bc_num *num)
-{
-  bc_num temp;
-
-  temp = bc_new_num ((*num)->n_len, 0);
-  temp->n_sign = (*num)->n_sign;
-  memcpy (temp->n_value, (*num)->n_value, (*num)->n_len);
-  bc_free_num (num);
-  *num = temp;
-}
-
-
-/* Raise BASE to the EXPO power, reduced modulo MOD.  The result is
-   placed in RESULT.  If a EXPO is not an integer,
-   only the integer part is used.  */
-
-int
-bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale)
+/* Raise BASE to the EXPO power, reduced modulo MOD.  The result is placed in RESULT. */
+zend_result bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale)
 {
   bc_num power, exponent, modulus, parity, temp;
   int rscale;
 
-  /* Check for correct numbers. */
-  if (bc_is_zero(mod)) return -1;
-  if (bc_is_neg(expo)) return -2;
+       /* Check the base for scale digits. */
+       if (base->n_scale != 0) {
+               /* 1st argument from PHP_FUNCTION(bcpowmod) */
+               zend_argument_value_error(1, "cannot have a fractional part");
+               return FAILURE;
+    }
+       /* Check the exponent for scale digits. */
+       if (expo->n_scale != 0) {
+               /* 2nd argument from PHP_FUNCTION(bcpowmod) */
+               zend_argument_value_error(2, "cannot have a fractional part");
+               return FAILURE;
+    }
+       if (bc_is_neg(expo)) {
+               zend_argument_value_error(2, "must be greater than or equal to 0");
+               return FAILURE;
+       }
+       /* Check the modulus for scale digits. */
+       if (mod->n_scale != 0) {
+               /* 3rd argument from PHP_FUNCTION(bcpowmod) */
+               zend_argument_value_error(3, "cannot have a fractional part");
+               return FAILURE;
+    }
+    /* Modulus cannot be 0 */
+       if (bc_is_zero(mod)) {
+               zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero");
+               return FAILURE;
+       }
 
   /* Set initial values.  */
   power = bc_copy_num (base);
@@ -76,27 +79,6 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale)
   temp = bc_copy_num (BCG(_one_));
   bc_init_num(&parity);
 
-  /* Check the base for scale digits. */
-  if (power->n_scale != 0)
-    {
-      php_error_docref (NULL, E_WARNING, "Non-zero scale in base");
-      _bc_truncate (&power);
-    }
-
-  /* Check the exponent for scale digits. */
-  if (exponent->n_scale != 0)
-    {
-      php_error_docref (NULL, E_WARNING, "Non-zero scale in exponent");
-      _bc_truncate (&exponent);
-    }
-
-  /* Check the modulus for scale digits. */
-  if (modulus->n_scale != 0)
-    {
-      php_error_docref (NULL, E_WARNING, "Non-zero scale in modulus");
-      _bc_truncate (&modulus);
-    }
-
   /* Do the calculation. */
   rscale = MAX(scale, power->n_scale);
   if ( !bc_compare(modulus, BCG(_one_)) )
@@ -127,5 +109,5 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale)
   bc_free_num (result);
   bc_free_num (&parity);
   *result = temp;
-  return 0;    /* Everything is OK. */
+  return SUCCESS;      /* Everything is OK. */
 }
index 822b70eb86127f2ceceb4e0953053f68dee2668a..38d9bda181bf0345659391e1ebed9bdb73537755 100644 (file)
@@ -6,8 +6,11 @@ if (!extension_loaded('bcmath')) die('skip bcmath extension is not available');
 ?>
 --FILE--
 <?php
-var_dump(bcpow('1', '1.1', 2));
+try {
+    var_dump(bcpow('1', '1.1', 2));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
 ?>
---EXPECTF--
-Warning: bcpow(): Non-zero scale in exponent in %s on line %d
-string(4) "1.00"
+--EXPECT--
+bcpow(): Argument #2 ($exponent) cannot have a fractional part
index 95c3f80b08b253b0ba01dd4523dda90aeb766512..d6271b18eb338d8fa32424558bee4c8598993845 100644 (file)
@@ -6,8 +6,11 @@ if (!extension_loaded('bcmath')) die('skip bcmath extension is not available');
 ?>
 --FILE--
 <?php
-var_dump(bcpow('0', '9223372036854775808', 2));
+try {
+    var_dump(bcpow('0', '9223372036854775808', 2));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
 ?>
---EXPECTF--
-Warning: bcpow(): Exponent too large in %s on line %d
-string(4) "1.00"
+--EXPECT--
+bcpow(): Argument #2 ($exponent) is too large
index 5f0fa8a93bcfe034ff38849fe954b18a3ac4c7df..c171e2d4a19d9ac07970e208291fd78ff8599f59 100644 (file)
@@ -6,11 +6,13 @@ bcpowmod() - Raise an arbitrary precision number to another, reduced by a specif
 bcmath.scale=0
 --FILE--
 <?php
-echo bcpowmod("5", "2", "7") . "\n";
-echo bcpowmod("-2", "5", "7") . "\n";
-echo bcpowmod("10", "2147483648", "2047");
+var_dump(bcpowmod("5", "2", "7"));
+var_dump(bcpowmod("-2", "5", "7"));
+var_dump(bcpowmod("10", "2147483648", "2047"));
+var_dump(bcpowmod("10", "0", "2047"));
 ?>
 --EXPECT--
-4
--4
-790
+string(1) "4"
+string(2) "-4"
+string(3) "790"
+string(1) "1"
index a72b39548b72b30a941db6a13f5afaff61278371..518f9eb0a98a59f21415f7bde487967b7f5e2c5a 100644 (file)
@@ -13,4 +13,4 @@ try {
 }
 ?>
 --EXPECT--
-bcpowmod(): Argument #2 ($exponent) must be greater than 0
+bcpowmod(): Argument #2 ($exponent) must be greater than or equal to 0
index 0b810969c6a79cf886badaf9f560e37eac87e3dc..bc30dc0afdeb0a41afed157e133c8f17355394a3 100644 (file)
@@ -7,7 +7,7 @@ Gabriel Caruso (carusogabriel34@gmail.com)
 --FILE--
 <?php
 try {
-    var_dump(bcpowmod('1', '-1', '0'));
+    var_dump(bcpowmod('1', '1', '0'));
 } catch (DivisionByZeroError $ex) {
     echo $ex->getMessage(), PHP_EOL;
 }
index bbc69f3952b007f0e9c8f51862dce568e57e62c3..83c85183f4080dbfd2c36a34d6c3546da7add3b0 100644 (file)
@@ -14,4 +14,4 @@ try {
 }
 ?>
 --EXPECT--
-Square root of negative number
+bcsqrt(): Argument #1 ($operand) must be greater than or equal to 0
index 7111bf6e3aca8eb9883d01067579d7e219c61c7c..3a6405d04a26c0411151f3319d3a71942aedbf51 100644 (file)
@@ -11,10 +11,12 @@ try {
 } catch (\ValueError $e) {
     echo $e->getMessage() . \PHP_EOL;
 }
-var_dump(bcpowmod(1, 1.2, 1, 1));
+try {
+    var_dump(bcpowmod(1, 1.2, 1, 1));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
 ?>
---EXPECTF--
+--EXPECT--
 bcpowmod(): Argument #4 ($scale) must be between 0 and 2147483647
-
-Warning: bcpowmod(): Non-zero scale in exponent in %s on line %d
-string(3) "0.0"
+bcpowmod(): Argument #2 ($exponent) cannot have a fractional part
index 2b7ab4b2c608b9950c5534296b09b8eee0fb8d4b..48044523840cf7576f27def68cc47e9d23189910 100644 (file)
@@ -6,12 +6,17 @@ 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));
+try {
+    var_dump(bcpowmod('4.1', '4', '3', 3));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
+try {
+    var_dump(bcpowmod('4', '4', '3.1', 3));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
 ?>
---EXPECTF--
-Warning: bcpowmod(): Non-zero scale in base in %s on line %d
-string(5) "1.000"
-
-Warning: bcpowmod(): Non-zero scale in modulus in %s on line %d
-string(5) "1.000"
+--EXPECT--
+bcpowmod(): Argument #1 ($base) cannot have a fractional part
+bcpowmod(): Argument #3 ($modulus) cannot have a fractional part
index 066d411c9006049dac2b2cc3ca2bdfe300571fdd..7edc666f752446e8eafc1fead7c89e4b616f16c1 100644 (file)
@@ -6,7 +6,11 @@ if (!extension_loaded('bcmath')) die('skip bcmath extension not available');
 ?>
 --FILE--
 <?php
-print @bcmul("\xB26483605105519922841849335928742092", bcpowmod(2, 65535, -4e-4));
+try {
+    print bcmul("\xB26483605105519922841849335928742092", bcpowmod(2, 65535, -4e-4));
+} catch (\ValueError $e) {
+    echo $e->getMessage() . \PHP_EOL;
+}
 ?>
 --EXPECT--
-0
+bcpowmod(): Argument #3 ($modulus) cannot have a fractional part