]> granicus.if.org Git - php/commitdiff
MFH: checks for negative values to gmp_sqrt(), gmp_powm(), gmp_sqrtrem()
authorAntony Dovgal <tony2001@php.net>
Tue, 1 Mar 2005 13:18:31 +0000 (13:18 +0000)
committerAntony Dovgal <tony2001@php.net>
Tue, 1 Mar 2005 13:18:31 +0000 (13:18 +0000)
and gmp_fact() to prevent SIGFPE
changed zend_error() to php_error_docref()

NEWS
ext/gmp/gmp.c

diff --git a/NEWS b/NEWS
index bcd698095a87cce3caa174399f0d84f33f512f21..f9a9cda103ef3d43152f66b371498277393d29f2 100644 (file)
--- 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)
index c834fbddcbb1c8c123512772f0a6bf0d4e98581b..7e13bc8dacd0d7ee07d6d62272891f8e128f7c1b 100644 (file)
@@ -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);