summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladyslav Startsev <17382248+vladyslavstartsev@users.noreply.github.com>2020-06-20 18:26:51 +0300
committerMáté Kocsis <kocsismate@woohoolabs.com>2020-06-22 09:31:55 +0200
commit2c97b401c61ad09ea0bb0045314b410a97e1d4ac (patch)
tree3cba1bfd15128c6d0c5692f51b2fa03082394885
parentec80b781dbd1978653b2e20d6b99ed61e65e646f (diff)
downloadphp-git-2c97b401c61ad09ea0bb0045314b410a97e1d4ac.tar.gz
make bcpowmod stricter by not returning false, instead throw exception
Closes GH-5747
-rw-r--r--ext/bcmath/bcmath.c14
-rw-r--r--ext/bcmath/bcmath.stub.php2
-rw-r--r--ext/bcmath/bcmath_arginfo.h2
-rw-r--r--ext/bcmath/libbcmath/src/raisemod.c2
-rw-r--r--ext/bcmath/tests/bcpowmod_negative_exponent.phpt16
-rw-r--r--ext/bcmath/tests/bcpowmod_zero_modulus.phpt (renamed from ext/bcmath/tests/bcpowmod_error4.phpt)12
-rw-r--r--ext/opcache/Optimizer/zend_func_info.c2
7 files changed, 39 insertions, 11 deletions
diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c
index 1b91fba72f..f1e298b5cc 100644
--- a/ext/bcmath/bcmath.c
+++ b/ext/bcmath/bcmath.c
@@ -404,10 +404,16 @@ PHP_FUNCTION(bcpowmod)
php_str2num(&second, ZSTR_VAL(right));
php_str2num(&mod, ZSTR_VAL(modulus));
- if (bc_raisemod(first, second, mod, &result, scale) != -1) {
- RETVAL_STR(bc_num2str_ex(result, scale));
- } else {
- RETVAL_FALSE;
+ 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;
}
bc_free_num(&first);
diff --git a/ext/bcmath/bcmath.stub.php b/ext/bcmath/bcmath.stub.php
index 45e75376f0..97232b0ed7 100644
--- a/ext/bcmath/bcmath.stub.php
+++ b/ext/bcmath/bcmath.stub.php
@@ -12,7 +12,7 @@ function bcdiv(string $dividend, string $divisor, ?int $scale = null): string {}
function bcmod(string $dividend, string $divisor, ?int $scale = null): string {}
-function bcpowmod(string $base, string $exponent, string $modulus, ?int $scale = null): string|false {}
+function bcpowmod(string $base, string $exponent, string $modulus, ?int $scale = null): string {}
function bcpow(string $base, string $exponent, ?int $scale = null): string {}
diff --git a/ext/bcmath/bcmath_arginfo.h b/ext/bcmath/bcmath_arginfo.h
index 75f864dc9d..46fc5ff9bd 100644
--- a/ext/bcmath/bcmath_arginfo.h
+++ b/ext/bcmath/bcmath_arginfo.h
@@ -18,7 +18,7 @@ ZEND_END_ARG_INFO()
#define arginfo_bcmod arginfo_bcdiv
-ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_bcpowmod, 0, 3, MAY_BE_STRING|MAY_BE_FALSE)
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_bcpowmod, 0, 3, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, base, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, exponent, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, modulus, IS_STRING, 0)
diff --git a/ext/bcmath/libbcmath/src/raisemod.c b/ext/bcmath/libbcmath/src/raisemod.c
index 2865903940..46dfd7a8a8 100644
--- a/ext/bcmath/libbcmath/src/raisemod.c
+++ b/ext/bcmath/libbcmath/src/raisemod.c
@@ -67,7 +67,7 @@ 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 -1;
+ if (bc_is_neg(expo)) return -2;
/* Set initial values. */
power = bc_copy_num (base);
diff --git a/ext/bcmath/tests/bcpowmod_negative_exponent.phpt b/ext/bcmath/tests/bcpowmod_negative_exponent.phpt
new file mode 100644
index 0000000000..a72b39548b
--- /dev/null
+++ b/ext/bcmath/tests/bcpowmod_negative_exponent.phpt
@@ -0,0 +1,16 @@
+--TEST--
+bc_raisemod's expo can't be negative
+--CREDITS--
+Gabriel Caruso (carusogabriel34@gmail.com)
+--SKIPIF--
+<?php if(!extension_loaded('bcmath')) die('skip bcmath extension not loaded'); ?>
+--FILE--
+<?php
+try {
+ var_dump(bcpowmod('1', '-1', '2'));
+} catch (\ValueError $e) {
+ echo $e->getMessage() . \PHP_EOL;
+}
+?>
+--EXPECT--
+bcpowmod(): Argument #2 ($exponent) must be greater than 0
diff --git a/ext/bcmath/tests/bcpowmod_error4.phpt b/ext/bcmath/tests/bcpowmod_zero_modulus.phpt
index 7c2ba5012b..0b810969c6 100644
--- a/ext/bcmath/tests/bcpowmod_error4.phpt
+++ b/ext/bcmath/tests/bcpowmod_zero_modulus.phpt
@@ -1,10 +1,16 @@
--TEST--
-bc_raisemod's mod can't be zero and expo can't be negative
+bc_raisemod's mod can't be zero
--CREDITS--
Gabriel Caruso (carusogabriel34@gmail.com)
--SKIPIF--
<?php if(!extension_loaded('bcmath')) die('skip bcmath extension not loaded'); ?>
--FILE--
-<?php var_dump(bcpowmod('1', '-1', '0')); ?>
+<?php
+try {
+ var_dump(bcpowmod('1', '-1', '0'));
+} catch (DivisionByZeroError $ex) {
+ echo $ex->getMessage(), PHP_EOL;
+}
+?>
--EXPECT--
-bool(false)
+Modulo by zero
diff --git a/ext/opcache/Optimizer/zend_func_info.c b/ext/opcache/Optimizer/zend_func_info.c
index ff985fc63f..1b9e800d7d 100644
--- a/ext/opcache/Optimizer/zend_func_info.c
+++ b/ext/opcache/Optimizer/zend_func_info.c
@@ -789,7 +789,7 @@ static const func_info_t func_infos[] = {
F1("bcmul", MAY_BE_STRING),
F1("bcdiv", MAY_BE_STRING),
F1("bcmod", MAY_BE_STRING),
- F1("bcpowmod", MAY_BE_FALSE | MAY_BE_STRING),
+ F1("bcpowmod", MAY_BE_STRING),
F1("bcpow", MAY_BE_STRING),
F1("bcsqrt", MAY_BE_STRING),