summaryrefslogtreecommitdiff
path: root/ext/gmp/gmp.c
diff options
context:
space:
mode:
authorAntony Dovgal <tony2001@php.net>2005-03-01 13:09:33 +0000
committerAntony Dovgal <tony2001@php.net>2005-03-01 13:09:33 +0000
commit6dac68f6698a6680e14aa7e6ae26efeff7e20864 (patch)
treea4c21f1df8d5485ac037c541e2c5bdc1f0ac3f61 /ext/gmp/gmp.c
parent67fd1f2654b8ff4cbca4c6e71e90e0843f2ffe99 (diff)
downloadphp-git-6dac68f6698a6680e14aa7e6ae26efeff7e20864.tar.gz
fix SIGFPE in gmp_powm(), gmp_sqrt() & gmp_sqrtrem() when using negative values
do not allow negative value to be passed to gmp_fact()
Diffstat (limited to 'ext/gmp/gmp.c')
-rw-r--r--ext/gmp/gmp.c53
1 files changed, 50 insertions, 3 deletions
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c
index f41b4063e3..afd6f7db37 100644
--- a/ext/gmp/gmp.c
+++ b/ext/gmp/gmp.c
@@ -781,7 +781,28 @@ ZEND_FUNCTION(gmp_abs)
Calculates factorial function */
ZEND_FUNCTION(gmp_fact)
{
- gmp_unary_ui_op(mpz_fac_ui);
+ zval **a_arg;
+ mpz_t *gmpnum_tmp;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ if (Z_TYPE_PP(a_arg) == IS_RESOURCE) {
+ FETCH_GMP_ZVAL(gmpnum_tmp, a_arg);
+ if (mpz_sgn(*gmpnum_tmp) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Number has to be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ } else {
+ convert_to_long_ex(a_arg);
+ if (Z_LVAL_PP(a_arg) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Number has to be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+ }
+
+ gmp_zval_unary_ui_op(return_value, a_arg, mpz_fac_ui);
}
/* }}} */
@@ -839,6 +860,10 @@ ZEND_FUNCTION(gmp_powm)
use_ui = 1;
} else {
FETCH_GMP_ZVAL(gmpnum_exp, exp_arg);
+ if (mpz_sgn(*gmpnum_exp) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Second parameter cannot be less than 0");
+ RETURN_FALSE;
+ }
}
FETCH_GMP_ZVAL(gmpnum_mod, mod_arg);
@@ -862,7 +887,24 @@ ZEND_FUNCTION(gmp_powm)
Takes integer part of square root of a */
ZEND_FUNCTION(gmp_sqrt)
{
- gmp_unary_op(mpz_sqrt);
+ zval **a_arg;
+ mpz_t *gmpnum_a, *gmpnum_result;
+
+ if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){
+ WRONG_PARAM_COUNT;
+ }
+
+ FETCH_GMP_ZVAL(gmpnum_a, a_arg);
+
+ if (mpz_sgn(*gmpnum_a) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Number has to be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+
+ INIT_GMP_NUM(gmpnum_result);
+ mpz_sqrt(*gmpnum_result, *gmpnum_a);
+
+ ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);
}
/* }}} */
@@ -879,7 +921,12 @@ ZEND_FUNCTION(gmp_sqrtrem)
}
FETCH_GMP_ZVAL(gmpnum_a, a_arg);
-
+
+ if (mpz_sgn(*gmpnum_a) < 0) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING,"Number has to be greater than or equal to 0");
+ RETURN_FALSE;
+ }
+
INIT_GMP_NUM(gmpnum_result1);
INIT_GMP_NUM(gmpnum_result2);