summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2005-04-25 12:03:27 +0000
committerStanislav Malyshev <stas@php.net>2005-04-25 12:03:27 +0000
commitcc83a160ee52c613a47bf02eadc7296124278cdf (patch)
tree11b19a97c0eab563479524ec46857abe1145698e
parentba9ef20412dd9e53b42666dc67adf7e51c3acb6d (diff)
downloadphp-git-cc83a160ee52c613a47bf02eadc7296124278cdf.tar.gz
Fix #32773 and made right fix for GMP FPEs
-rw-r--r--ext/gmp/gmp.c62
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);
}
/* }}} */