diff options
author | Stanislav Malyshev <stas@php.net> | 2005-04-25 12:03:27 +0000 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2005-04-25 12:03:27 +0000 |
commit | cc83a160ee52c613a47bf02eadc7296124278cdf (patch) | |
tree | 11b19a97c0eab563479524ec46857abe1145698e | |
parent | ba9ef20412dd9e53b42666dc67adf7e51c3acb6d (diff) | |
download | php-git-cc83a160ee52c613a47bf02eadc7296124278cdf.tar.gz |
Fix #32773 and made right fix for GMP FPEs
-rw-r--r-- | ext/gmp/gmp.c | 62 |
1 files changed, 47 insertions, 15 deletions
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index eb1d85a120..eab64aba36 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -280,8 +280,8 @@ typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr); typedef unsigned long (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long); /* }}} */ -#define gmp_zval_binary_ui_op(r, a, b, o, u) gmp_zval_binary_ui_op_ex(r, a, b, o, u, 0 TSRMLS_CC) -#define gmp_zval_binary_ui_op2(r, a, b, o, u) gmp_zval_binary_ui_op2_ex(r, a, b, o, u, 0 TSRMLS_CC) +#define gmp_zval_binary_ui_op(r, a, b, o, u) gmp_zval_binary_ui_op_ex(r, a, b, o, u, 0, 0 TSRMLS_CC) +#define gmp_zval_binary_ui_op2(r, a, b, o, u) gmp_zval_binary_ui_op2_ex(r, a, b, o, u, 0, 0 TSRMLS_CC) #define gmp_binary_ui_op(op, uop) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, uop) #define gmp_binary_op(op) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, NULL) @@ -292,11 +292,13 @@ typedef unsigned long (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsig #define gmp_unary_opl(op) _gmp_unary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) #define gmp_unary_ui_op(op) _gmp_unary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op) +typedef int (*gmp_validate_params_t)(mpz_ptr); + /* {{{ gmp_zval_binary_ui_op_ex Execute GMP binary operation. May return GMP resource or long if operation allows this */ -static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int allow_ui_return TSRMLS_DC) +static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op_t gmp_op, gmp_binary_ui_op_t gmp_ui_op, int allow_ui_return, int check_b_zero TSRMLS_DC) { mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result; unsigned long long_result=0; @@ -309,6 +311,20 @@ static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zv FETCH_GMP_ZVAL(gmpnum_b, b_arg); } + if(check_b_zero) { + int b_is_zero = 0; + if(use_ui) { + b_is_zero = (Z_LVAL_PP(b_arg) == 0); + } else { + b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0); + } + + if(b_is_zero) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed"); + RETURN_FALSE; + } + } + INIT_GMP_NUM(gmpnum_result); if(use_ui && gmp_ui_op) { if(allow_ui_return) { @@ -333,7 +349,7 @@ static inline void gmp_zval_binary_ui_op_ex(zval *return_value, zval **a_arg, zv Execute GMP binary operation which returns 2 values. May return GMP resources or longs if operation allows this. */ -static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int allow_ui_return TSRMLS_DC) +static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, zval **b_arg, gmp_binary_op2_t gmp_op, gmp_binary_ui_op2_t gmp_ui_op, int allow_ui_return, int check_b_zero TSRMLS_DC) { mpz_t *gmpnum_a, *gmpnum_b, *gmpnum_result1, *gmpnum_result2; zval r; @@ -348,6 +364,20 @@ static inline void gmp_zval_binary_ui_op2_ex(zval *return_value, zval **a_arg, z FETCH_GMP_ZVAL(gmpnum_b, b_arg); } + if(check_b_zero) { + int b_is_zero = 0; + if(use_ui) { + b_is_zero = (Z_LVAL_PP(b_arg) == 0); + } else { + b_is_zero = !mpz_cmp_ui(*gmpnum_b, 0); + } + + if(b_is_zero) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zero operand not allowed"); + RETURN_FALSE; + } + } + INIT_GMP_NUM(gmpnum_result1); INIT_GMP_NUM(gmpnum_result2); @@ -634,13 +664,13 @@ ZEND_FUNCTION(gmp_div_qr) switch(round) { case GMP_ROUND_ZERO: - gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_tdiv_qr, (gmp_binary_ui_op2_t)mpz_tdiv_qr_ui); + gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_tdiv_qr, (gmp_binary_ui_op2_t)mpz_tdiv_qr_ui, 0, 1 TSRMLS_CC); break; case GMP_ROUND_PLUSINF: - gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_cdiv_qr, (gmp_binary_ui_op2_t)mpz_cdiv_qr_ui); + gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_cdiv_qr, (gmp_binary_ui_op2_t)mpz_cdiv_qr_ui, 0, 1 TSRMLS_CC); break; case GMP_ROUND_MINUSINF: - gmp_zval_binary_ui_op2(return_value, a_arg, b_arg, mpz_fdiv_qr, (gmp_binary_ui_op2_t)mpz_fdiv_qr_ui); + gmp_zval_binary_ui_op2_ex(return_value, a_arg, b_arg, mpz_fdiv_qr, (gmp_binary_ui_op2_t)mpz_fdiv_qr_ui, 0, 1 TSRMLS_CC); break; } @@ -669,15 +699,17 @@ ZEND_FUNCTION(gmp_div_r) break; } + + switch(round) { case GMP_ROUND_ZERO: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_r, (gmp_binary_ui_op_t)mpz_tdiv_r_ui, 1 TSRMLS_CC); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_r, (gmp_binary_ui_op_t)mpz_tdiv_r_ui, 1, 1 TSRMLS_CC); break; case GMP_ROUND_PLUSINF: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_r, (gmp_binary_ui_op_t)mpz_cdiv_r_ui, 1 TSRMLS_CC); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_r, (gmp_binary_ui_op_t)mpz_cdiv_r_ui, 1, 1 TSRMLS_CC); break; case GMP_ROUND_MINUSINF: - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_r, (gmp_binary_ui_op_t)mpz_fdiv_r_ui, 1 TSRMLS_CC); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_r, (gmp_binary_ui_op_t)mpz_fdiv_r_ui, 1, 1 TSRMLS_CC); break; } } @@ -707,13 +739,13 @@ ZEND_FUNCTION(gmp_div_q) switch(round) { case GMP_ROUND_ZERO: - gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_tdiv_q, (gmp_binary_ui_op_t)mpz_tdiv_q_ui); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_tdiv_q, (gmp_binary_ui_op_t)mpz_tdiv_q_ui, 0, 1 TSRMLS_CC); break; case GMP_ROUND_PLUSINF: - gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_cdiv_q, (gmp_binary_ui_op_t)mpz_cdiv_q_ui); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_cdiv_q, (gmp_binary_ui_op_t)mpz_cdiv_q_ui, 0, 1 TSRMLS_CC); break; case GMP_ROUND_MINUSINF: - gmp_zval_binary_ui_op(return_value, a_arg, b_arg, mpz_fdiv_q, (gmp_binary_ui_op_t)mpz_fdiv_q_ui); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_fdiv_q, (gmp_binary_ui_op_t)mpz_fdiv_q_ui, 0, 1 TSRMLS_CC); break; } @@ -730,7 +762,7 @@ ZEND_FUNCTION(gmp_mod) WRONG_PARAM_COUNT; } - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_mod, (gmp_binary_ui_op_t)mpz_mod_ui, 1 TSRMLS_CC); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_mod, (gmp_binary_ui_op_t)mpz_mod_ui, 1, 1 TSRMLS_CC); } /* }}} */ @@ -976,7 +1008,7 @@ ZEND_FUNCTION(gmp_gcd) WRONG_PARAM_COUNT; } - gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_gcd, (gmp_binary_ui_op_t)mpz_gcd_ui, 1 TSRMLS_CC); + gmp_zval_binary_ui_op_ex(return_value, a_arg, b_arg, mpz_gcd, (gmp_binary_ui_op_t)mpz_gcd_ui, 1, 0 TSRMLS_CC); } /* }}} */ |