From 3fdc0745f15633d5b579acbcf227ddadbfe12227 Mon Sep 17 00:00:00 2001 From: Antony Dovgal Date: Tue, 1 Mar 2005 13:18:31 +0000 Subject: [PATCH] MFH: checks for negative values to gmp_sqrt(), gmp_powm(), gmp_sqrtrem() and gmp_fact() to prevent SIGFPE changed zend_error() to php_error_docref() --- NEWS | 2 ++ ext/gmp/gmp.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index bcd698095a..f9a9cda103 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,8 @@ PHP 4 NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, Version 4.3.11 - Added Oracle Instant Client support. (cjbj at hotmail dot com, Tony) +- Added checks for negative values to gmp_sqrt(), gmp_powm(), gmp_sqrtrem() + and gmp_fact() to prevent SIGFPE. (Tony) - Changed phpize not to require libtool. (Jani) - Updated bundled libmbfl library (used for multibyte functions). (Moriyoshi) - Fixed bug #32114 (DOM crashing when attribute appended to Document). (Rob) diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index c834fbddcb..7e13bc8dac 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -251,7 +251,7 @@ static int convert_to_gmp(mpz_t * *gmpnumber, zval **val, int base) } break; default: - zend_error(E_WARNING,"Unable to convert variable to GMP - wrong type"); + php_error_docref(NULL TSRMLS_CC, E_WARNING,"Unable to convert variable to GMP - wrong type"); efree(*gmpnumber); return FAILURE; } @@ -504,7 +504,7 @@ ZEND_FUNCTION(gmp_init) convert_to_long_ex(base_arg); base = Z_LVAL_PP(base_arg); if(base < 2 || base > 36) { - zend_error(E_WARNING, "Bad base for conversion: %d (should be between 2 and 36)", base); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad base for conversion: %d (should be between 2 and 36)", base); RETURN_FALSE; } } @@ -566,7 +566,7 @@ ZEND_FUNCTION(gmp_strval) } if(base < 2 || base > 36) { - zend_error(E_WARNING, "Bad base for conversion: %d", base); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad base for conversion: %d", base); RETURN_FALSE; } @@ -770,7 +770,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); } /* }}} */ @@ -795,7 +816,7 @@ ZEND_FUNCTION(gmp_pow) convert_to_long_ex(exp_arg); if(Z_LVAL_PP(exp_arg) < 0) { - zend_error(E_WARNING,"Negative exponent not supported"); + php_error_docref(NULL TSRMLS_CC, E_WARNING,"Negative exponent not supported"); RETURN_FALSE; } @@ -827,6 +848,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); @@ -850,7 +875,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); } /* }}} */ @@ -868,6 +910,11 @@ 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); -- 2.50.1