From 1c7b617f4ef5d662b8977c009b8d091a98ab4768 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 17:51:37 +0200 Subject: [PATCH 01/11] Show argument number for bcsqrt when operand is negative --- ext/bcmath/bcmath.c | 2 +- ext/bcmath/tests/bcsqrt_error1.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 17f28f1781a32..058b5faf36c9b 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -481,7 +481,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, "cannot take square root of a negative number"); } bc_free_num(&result); diff --git a/ext/bcmath/tests/bcsqrt_error1.phpt b/ext/bcmath/tests/bcsqrt_error1.phpt index bbc69f3952b00..9ab6dbd48b09c 100644 --- a/ext/bcmath/tests/bcsqrt_error1.phpt +++ b/ext/bcmath/tests/bcsqrt_error1.phpt @@ -14,4 +14,4 @@ try { } ?> --EXPECT-- -Square root of negative number +bcsqrt(): Argument #1 ($operand) cannot take square root of a negative number From 825c0ee8747afd9a0b039e2f7a0a469c2e4861e6 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:00:10 +0200 Subject: [PATCH 02/11] Promote to a catchable error a condition which needs special crafted data --- ext/bcmath/libbcmath/src/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index 676076f89ddb0..0a7a46f569c3c 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -45,8 +45,8 @@ _bc_new_num_ex (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); + if ((size_t)length + (size_t)scale > INT_MAX) { + zend_throw_error(NULL, "Result exceeds the length a PHP string can hold"); } /* PHP Change: malloc() -> pemalloc(), removed free_list code */ temp = (bc_num) safe_pemalloc (1, sizeof(bc_struct)+length, scale, persistent); From 3677786da731bc9d7817d30b2ec978f93bf3f65e Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:13:01 +0200 Subject: [PATCH 03/11] Warning to error promotion for bcpow() --- ext/bcmath/libbcmath/src/raise.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index 700a50f50c085..1f8fba913ce1b 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -52,12 +52,16 @@ 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, "must be an integer"); + } + 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"); + } /* Special case if exponent is a zero. */ if (exponent == 0) From 530b7164d4011168116a9049fe8888f1344eb890 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:17:46 +0200 Subject: [PATCH 04/11] Test fixes --- ext/bcmath/tests/bcpow_error1.phpt | 11 +++++++---- ext/bcmath/tests/bcpow_error2.phpt | 11 +++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/ext/bcmath/tests/bcpow_error1.phpt b/ext/bcmath/tests/bcpow_error1.phpt index 822b70eb86127..80494a5041a0f 100644 --- a/ext/bcmath/tests/bcpow_error1.phpt +++ b/ext/bcmath/tests/bcpow_error1.phpt @@ -6,8 +6,11 @@ if (!extension_loaded('bcmath')) die('skip bcmath extension is not available'); ?> --FILE-- 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) must be an integer diff --git a/ext/bcmath/tests/bcpow_error2.phpt b/ext/bcmath/tests/bcpow_error2.phpt index 95c3f80b08b25..d6271b18eb338 100644 --- a/ext/bcmath/tests/bcpow_error2.phpt +++ b/ext/bcmath/tests/bcpow_error2.phpt @@ -6,8 +6,11 @@ if (!extension_loaded('bcmath')) die('skip bcmath extension is not available'); ?> --FILE-- 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 From c94d0537eae971b2a1b5ab75ee63e74cbb8bb345 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:34:44 +0200 Subject: [PATCH 05/11] Warning to Error promotion in bcpowmod() --- ext/bcmath/bcmath.c | 3 +++ ext/bcmath/libbcmath/src/raisemod.c | 39 +++++++++++++---------------- ext/bcmath/tests/bug72093.phpt | 12 +++++---- ext/bcmath/tests/bug75178.phpt | 21 ++++++++++------ ext/bcmath/tests/bug78878.phpt | 8 ++++-- 5 files changed, 47 insertions(+), 36 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 058b5faf36c9b..101b10fbda2ba 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -403,6 +403,9 @@ PHP_FUNCTION(bcpowmod) case -2: zend_argument_value_error(2, "must be greater than 0"); break; + case -3: + /* ValueError thrown in bc_raisemod() */ + break; } bc_free_num(&first); diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index 46dfd7a8a863a..1b70014d93e81 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -68,6 +68,24 @@ bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) /* 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, "must be an integer"); + return -3; + } + /* Check the exponent for scale digits. */ + if (expo->n_scale != 0) { + /* 2nd argument from PHP_FUNCTION(bcpowmod) */ + zend_argument_value_error(2, "must be an integer"); + return -3; + } + /* Check the modulus for scale digits. */ + if (mod->n_scale != 0) { + /* 3rd argument from PHP_FUNCTION(bcpowmod) */ + zend_argument_value_error(3, "must be an integer"); + return -3; + } /* Set initial values. */ power = bc_copy_num (base); @@ -76,27 +94,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_)) ) diff --git a/ext/bcmath/tests/bug72093.phpt b/ext/bcmath/tests/bug72093.phpt index 7111bf6e3aca8..a266ab4ed8af0 100644 --- a/ext/bcmath/tests/bug72093.phpt +++ b/ext/bcmath/tests/bug72093.phpt @@ -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) must be an integer diff --git a/ext/bcmath/tests/bug75178.phpt b/ext/bcmath/tests/bug75178.phpt index 2b7ab4b2c608b..cbb11d5135671 100644 --- a/ext/bcmath/tests/bug75178.phpt +++ b/ext/bcmath/tests/bug75178.phpt @@ -6,12 +6,17 @@ if (!extension_loaded('bcmath')) die('skip bcmath extension is not available'); ?> --FILE-- 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) must be an integer +bcpowmod(): Argument #3 ($modulus) must be an integer diff --git a/ext/bcmath/tests/bug78878.phpt b/ext/bcmath/tests/bug78878.phpt index 066d411c90060..60b2ed1ec7ebc 100644 --- a/ext/bcmath/tests/bug78878.phpt +++ b/ext/bcmath/tests/bug78878.phpt @@ -6,7 +6,11 @@ if (!extension_loaded('bcmath')) die('skip bcmath extension not available'); ?> --FILE-- getMessage() . \PHP_EOL; +} ?> --EXPECT-- -0 +bcpowmod(): Argument #3 ($modulus) must be an integer From 03448b2bd651b6bced320c94aad046461fff964e Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:45:17 +0200 Subject: [PATCH 06/11] W.I.P. Clean up raisemod implementation --- ext/bcmath/libbcmath/src/raisemod.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index 1b70014d93e81..ce787841b1a59 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -62,7 +62,7 @@ _bc_truncate (bc_num *num) int bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) { - bc_num power, exponent, modulus, parity, temp; + bc_num parity, temp; int rscale; /* Check for correct numbers. */ @@ -88,39 +88,33 @@ 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); /* Do the calculation. */ - rscale = MAX(scale, power->n_scale); - if ( !bc_compare(modulus, BCG(_one_)) ) + rscale = MAX(scale, base->n_scale); + if ( !bc_compare(mod, BCG(_one_)) ) { bc_free_num (&temp); temp = bc_new_num (1, scale); } else { - while ( !bc_is_zero(exponent) ) + while ( !bc_is_zero(expo) ) { - (void) bc_divmod (exponent, BCG(_two_), &exponent, &parity, 0); + (void) bc_divmod (expo, BCG(_two_), &expo, &parity, 0); if ( !bc_is_zero(parity) ) { - bc_multiply (temp, power, &temp, rscale); - (void) bc_modulo (temp, modulus, &temp, scale); + bc_multiply (temp, base, &temp, rscale); + (void) bc_modulo (temp, mod, &temp, scale); } - bc_multiply (power, power, &power, rscale); - (void) bc_modulo (power, modulus, &power, scale); + bc_multiply (base, base, &base, rscale); + (void) bc_modulo (base, mod, &base, 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; From 8c54e62b17e24e1444413d5361da0a2726b04b86 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:46:01 +0200 Subject: [PATCH 07/11] Revert "W.I.P. Clean up raisemod implementation" This reverts commit 71e8769a4c059da5dfd6632825858f12c88d2346. --- ext/bcmath/libbcmath/src/raisemod.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index ce787841b1a59..1b70014d93e81 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -62,7 +62,7 @@ _bc_truncate (bc_num *num) int bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) { - bc_num parity, temp; + bc_num power, exponent, modulus, parity, temp; int rscale; /* Check for correct numbers. */ @@ -88,33 +88,39 @@ 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); /* 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_)) ) { bc_free_num (&temp); temp = bc_new_num (1, scale); } else { - while ( !bc_is_zero(expo) ) + while ( !bc_is_zero(exponent) ) { - (void) bc_divmod (expo, BCG(_two_), &expo, &parity, 0); + (void) bc_divmod (exponent, BCG(_two_), &exponent, &parity, 0); if ( !bc_is_zero(parity) ) { - bc_multiply (temp, base, &temp, rscale); - (void) bc_modulo (temp, mod, &temp, scale); + bc_multiply (temp, power, &temp, rscale); + (void) bc_modulo (temp, modulus, &temp, scale); } - bc_multiply (base, base, &base, rscale); - (void) bc_modulo (base, mod, &base, scale); + bc_multiply (power, power, &power, rscale); + (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; From 2cc16b8b8f0fac380a310c34cafc320b8160cc52 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:46:49 +0200 Subject: [PATCH 08/11] Cleanup --- ext/bcmath/libbcmath/src/raisemod.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index 1b70014d93e81..68bd062dde163 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -37,30 +37,8 @@ #include "bcmath.h" #include "private.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. */ +int 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; From f1ba1765b893ff212a44a66b789411ca5a764b36 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 18:56:42 +0200 Subject: [PATCH 09/11] Refactor ValueError handling for bcpowmod() --- ext/bcmath/bcmath.c | 15 ++---------- ext/bcmath/libbcmath/src/raisemod.c | 23 ++++++++++++------- ext/bcmath/tests/bcpowmod.phpt | 14 ++++++----- .../tests/bcpowmod_negative_exponent.phpt | 2 +- ext/bcmath/tests/bcpowmod_zero_modulus.phpt | 2 +- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 101b10fbda2ba..5c0f94e00771e 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -393,19 +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; - case -3: - /* ValueError thrown in bc_raisemod() */ - break; + if (bc_raisemod(first, second, mod, &result, scale) == SUCCESS) { + RETVAL_STR(bc_num2str_ex(result, scale)); } bc_free_num(&first); diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index 68bd062dde163..6cde898e6281e 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -36,34 +36,41 @@ #include #include "bcmath.h" #include "private.h" +#include "zend_exceptions.h" /* Raise BASE to the EXPO power, reduced modulo MOD. The result is placed in RESULT. */ -int bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, int scale) +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, "must be an integer"); - return -3; + return FAILURE; } /* Check the exponent for scale digits. */ if (expo->n_scale != 0) { /* 2nd argument from PHP_FUNCTION(bcpowmod) */ zend_argument_value_error(2, "must be an integer"); - return -3; + 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, "must be an integer"); - return -3; + 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); @@ -102,5 +109,5 @@ int 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. */ } diff --git a/ext/bcmath/tests/bcpowmod.phpt b/ext/bcmath/tests/bcpowmod.phpt index 5f0fa8a93bcfe..c171e2d4a19d9 100644 --- a/ext/bcmath/tests/bcpowmod.phpt +++ b/ext/bcmath/tests/bcpowmod.phpt @@ -6,11 +6,13 @@ bcpowmod() - Raise an arbitrary precision number to another, reduced by a specif bcmath.scale=0 --FILE-- --EXPECT-- -4 --4 -790 +string(1) "4" +string(2) "-4" +string(3) "790" +string(1) "1" diff --git a/ext/bcmath/tests/bcpowmod_negative_exponent.phpt b/ext/bcmath/tests/bcpowmod_negative_exponent.phpt index a72b39548b72b..518f9eb0a98a5 100644 --- a/ext/bcmath/tests/bcpowmod_negative_exponent.phpt +++ b/ext/bcmath/tests/bcpowmod_negative_exponent.phpt @@ -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 diff --git a/ext/bcmath/tests/bcpowmod_zero_modulus.phpt b/ext/bcmath/tests/bcpowmod_zero_modulus.phpt index 0b810969c6a79..bc30dc0afdeb0 100644 --- a/ext/bcmath/tests/bcpowmod_zero_modulus.phpt +++ b/ext/bcmath/tests/bcpowmod_zero_modulus.phpt @@ -7,7 +7,7 @@ Gabriel Caruso (carusogabriel34@gmail.com) --FILE-- getMessage(), PHP_EOL; } From c2a0b78afe6d6bb45165d99b8568fb1192b7c1f9 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Wed, 9 Sep 2020 19:13:02 +0200 Subject: [PATCH 10/11] zend_string_alloc() should already exit when OOM --- ext/bcmath/config.m4 | 2 +- ext/bcmath/config.w32 | 2 +- ext/bcmath/libbcmath/src/bcmath.h | 3 -- ext/bcmath/libbcmath/src/num2str.c | 1 - ext/bcmath/libbcmath/src/outofmem.c | 44 ----------------------------- 5 files changed, 2 insertions(+), 50 deletions(-) delete mode 100644 ext/bcmath/libbcmath/src/outofmem.c diff --git a/ext/bcmath/config.m4 b/ext/bcmath/config.m4 index 2877a7d4adab0..ee9fa3f3c9e1c 100644 --- a/ext/bcmath/config.m4 +++ b/ext/bcmath/config.m4 @@ -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, diff --git a/ext/bcmath/config.w32 b/ext/bcmath/config.w32 index eaf217774d31d..04ffa31d58384 100644 --- a/ext/bcmath/config.w32 +++ b/ext/bcmath/config.w32 @@ -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"); diff --git a/ext/bcmath/libbcmath/src/bcmath.h b/ext/bcmath/libbcmath/src/bcmath.h index becba7ec3e2db..24425544bb2f6 100644 --- a/ext/bcmath/libbcmath/src/bcmath.h +++ b/ext/bcmath/libbcmath/src/bcmath.h @@ -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)) diff --git a/ext/bcmath/libbcmath/src/num2str.c b/ext/bcmath/libbcmath/src/num2str.c index 23988c0d6c5db..3e23158125282 100644 --- a/ext/bcmath/libbcmath/src/num2str.c +++ b/ext/bcmath/libbcmath/src/num2str.c @@ -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 index cb2f1085a5f90..0000000000000 --- a/ext/bcmath/libbcmath/src/outofmem.c +++ /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 -#include -#include -#include -#include -#include "bcmath.h" -#include "private.h" - - -void bc_out_of_memory (void) -{ - zend_error(E_ERROR, "bcmath: out of memory!"); -} From ba4109ec30f3e758dcf10e27e5cb6e87e2fa9b24 Mon Sep 17 00:00:00 2001 From: George Peter Banyard Date: Fri, 11 Sep 2020 15:55:46 +0200 Subject: [PATCH 11/11] Reviews --- ext/bcmath/bcmath.c | 2 +- ext/bcmath/libbcmath/src/init.c | 4 ---- ext/bcmath/libbcmath/src/raise.c | 4 +++- ext/bcmath/libbcmath/src/raisemod.c | 6 +++--- ext/bcmath/tests/bcpow_error1.phpt | 2 +- ext/bcmath/tests/bcsqrt_error1.phpt | 2 +- ext/bcmath/tests/bug72093.phpt | 2 +- ext/bcmath/tests/bug75178.phpt | 4 ++-- ext/bcmath/tests/bug78878.phpt | 2 +- 9 files changed, 13 insertions(+), 15 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 5c0f94e00771e..f20dda534fd26 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -473,7 +473,7 @@ PHP_FUNCTION(bcsqrt) if (bc_sqrt (&result, scale) != 0) { RETVAL_STR(bc_num2str_ex(result, scale)); } else { - zend_argument_value_error(1, "cannot take square root of a negative number"); + zend_argument_value_error(1, "must be greater than or equal to 0"); } bc_free_num(&result); diff --git a/ext/bcmath/libbcmath/src/init.c b/ext/bcmath/libbcmath/src/init.c index 0a7a46f569c3c..96e934b34da76 100644 --- a/ext/bcmath/libbcmath/src/init.c +++ b/ext/bcmath/libbcmath/src/init.c @@ -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_throw_error(NULL, "Result exceeds the length a PHP string can hold"); - } /* PHP Change: malloc() -> pemalloc(), removed free_list code */ temp = (bc_num) safe_pemalloc (1, sizeof(bc_struct)+length, scale, persistent); temp->n_sign = PLUS; diff --git a/ext/bcmath/libbcmath/src/raise.c b/ext/bcmath/libbcmath/src/raise.c index 1f8fba913ce1b..2e843f179a6d6 100644 --- a/ext/bcmath/libbcmath/src/raise.c +++ b/ext/bcmath/libbcmath/src/raise.c @@ -55,12 +55,14 @@ bc_raise (bc_num num1, bc_num num2, bc_num *result, int scale) /* 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, "must be an integer"); + 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. */ diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c index 6cde898e6281e..bb0d16f6f0a55 100644 --- a/ext/bcmath/libbcmath/src/raisemod.c +++ b/ext/bcmath/libbcmath/src/raisemod.c @@ -47,13 +47,13 @@ zend_result bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, i /* Check the base for scale digits. */ if (base->n_scale != 0) { /* 1st argument from PHP_FUNCTION(bcpowmod) */ - zend_argument_value_error(1, "must be an integer"); + 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, "must be an integer"); + zend_argument_value_error(2, "cannot have a fractional part"); return FAILURE; } if (bc_is_neg(expo)) { @@ -63,7 +63,7 @@ zend_result bc_raisemod (bc_num base, bc_num expo, bc_num mod, bc_num *result, i /* Check the modulus for scale digits. */ if (mod->n_scale != 0) { /* 3rd argument from PHP_FUNCTION(bcpowmod) */ - zend_argument_value_error(3, "must be an integer"); + zend_argument_value_error(3, "cannot have a fractional part"); return FAILURE; } /* Modulus cannot be 0 */ diff --git a/ext/bcmath/tests/bcpow_error1.phpt b/ext/bcmath/tests/bcpow_error1.phpt index 80494a5041a0f..38d9bda181bf0 100644 --- a/ext/bcmath/tests/bcpow_error1.phpt +++ b/ext/bcmath/tests/bcpow_error1.phpt @@ -13,4 +13,4 @@ try { } ?> --EXPECT-- -bcpow(): Argument #2 ($exponent) must be an integer +bcpow(): Argument #2 ($exponent) cannot have a fractional part diff --git a/ext/bcmath/tests/bcsqrt_error1.phpt b/ext/bcmath/tests/bcsqrt_error1.phpt index 9ab6dbd48b09c..83c85183f4080 100644 --- a/ext/bcmath/tests/bcsqrt_error1.phpt +++ b/ext/bcmath/tests/bcsqrt_error1.phpt @@ -14,4 +14,4 @@ try { } ?> --EXPECT-- -bcsqrt(): Argument #1 ($operand) cannot take square root of a negative number +bcsqrt(): Argument #1 ($operand) must be greater than or equal to 0 diff --git a/ext/bcmath/tests/bug72093.phpt b/ext/bcmath/tests/bug72093.phpt index a266ab4ed8af0..3a6405d04a26c 100644 --- a/ext/bcmath/tests/bug72093.phpt +++ b/ext/bcmath/tests/bug72093.phpt @@ -19,4 +19,4 @@ try { ?> --EXPECT-- bcpowmod(): Argument #4 ($scale) must be between 0 and 2147483647 -bcpowmod(): Argument #2 ($exponent) must be an integer +bcpowmod(): Argument #2 ($exponent) cannot have a fractional part diff --git a/ext/bcmath/tests/bug75178.phpt b/ext/bcmath/tests/bug75178.phpt index cbb11d5135671..48044523840cf 100644 --- a/ext/bcmath/tests/bug75178.phpt +++ b/ext/bcmath/tests/bug75178.phpt @@ -18,5 +18,5 @@ try { } ?> --EXPECT-- -bcpowmod(): Argument #1 ($base) must be an integer -bcpowmod(): Argument #3 ($modulus) must be an integer +bcpowmod(): Argument #1 ($base) cannot have a fractional part +bcpowmod(): Argument #3 ($modulus) cannot have a fractional part diff --git a/ext/bcmath/tests/bug78878.phpt b/ext/bcmath/tests/bug78878.phpt index 60b2ed1ec7ebc..7edc666f75244 100644 --- a/ext/bcmath/tests/bug78878.phpt +++ b/ext/bcmath/tests/bug78878.phpt @@ -13,4 +13,4 @@ try { } ?> --EXPECT-- -bcpowmod(): Argument #3 ($modulus) must be an integer +bcpowmod(): Argument #3 ($modulus) cannot have a fractional part