summaryrefslogtreecommitdiff
path: root/Zend/zend_operators.c
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-06-28 18:22:10 +0200
committerBob Weinand <bobwei9@hotmail.com>2015-06-28 18:22:59 +0200
commitfb08798c9f0ea820d567668d0cea4833dc61dd8e (patch)
treef8a0be22eb7e68f2b244d994120d54544b40e1d1 /Zend/zend_operators.c
parent64c371142cbdb82eb0879d247430797d73a8ac2d (diff)
downloadphp-git-fb08798c9f0ea820d567668d0cea4833dc61dd8e.tar.gz
Fix bug #69957 (Different ways of handling div/mod by zero)
Diffstat (limited to 'Zend/zend_operators.c')
-rw-r--r--Zend/zend_operators.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index d9670a5a49..9439296657 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -1103,16 +1103,19 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {
while (1) {
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
case TYPE_PAIR(IS_LONG, IS_LONG):
- if (Z_LVAL_P(op2) == 0) {
- zend_error(E_WARNING, "Division by zero");
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ if (EG(current_execute_data) && !CG(in_compilation)) {
+ zend_error(E_ERROR | E_EXCEPTION, "Division by zero");
+ } else {
+ zend_error_noreturn(E_ERROR, "Division by zero");
+ }
ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1) / (double) Z_LVAL_P(op2)));
return SUCCESS;
- } else if (Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN) {
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
/* Prevent overflow error/crash */
ZVAL_DOUBLE(result, (double) ZEND_LONG_MIN / -1);
return SUCCESS;
- }
- if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
+ } else if (Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0) { /* integer */
ZVAL_LONG(result, Z_LVAL_P(op1) / Z_LVAL_P(op2));
} else {
ZVAL_DOUBLE(result, ((double) Z_LVAL_P(op1)) / Z_LVAL_P(op2));
@@ -1120,22 +1123,34 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {
return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_LONG):
- if (Z_LVAL_P(op2) == 0) {
- zend_error(E_WARNING, "Division by zero");
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ if (EG(current_execute_data) && !CG(in_compilation)) {
+ zend_error(E_ERROR | E_EXCEPTION, "Division by zero");
+ } else {
+ zend_error_noreturn(E_ERROR, "Division by zero");
+ }
}
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / (double)Z_LVAL_P(op2));
return SUCCESS;
case TYPE_PAIR(IS_LONG, IS_DOUBLE):
- if (Z_DVAL_P(op2) == 0) {
- zend_error(E_WARNING, "Division by zero");
+ if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
+ if (EG(current_execute_data) && !CG(in_compilation)) {
+ zend_error(E_ERROR | E_EXCEPTION, "Division by zero");
+ } else {
+ zend_error_noreturn(E_ERROR, "Division by zero");
+ }
}
ZVAL_DOUBLE(result, (double)Z_LVAL_P(op1) / Z_DVAL_P(op2));
return SUCCESS;
case TYPE_PAIR(IS_DOUBLE, IS_DOUBLE):
- if (Z_DVAL_P(op2) == 0) {
- zend_error(E_WARNING, "Division by zero");
+ if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
+ if (EG(current_execute_data) && !CG(in_compilation)) {
+ zend_error(E_ERROR | E_EXCEPTION, "Division by zero");
+ } else {
+ zend_error_noreturn(E_ERROR, "Division by zero");
+ }
}
ZVAL_DOUBLE(result, Z_DVAL_P(op1) / Z_DVAL_P(op2));
return SUCCESS;
@@ -1170,24 +1185,21 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {
zval_dtor(result);
}
- if (op2_lval == 0) {
+ if (UNEXPECTED(op2_lval == 0)) {
/* modulus by zero */
if (EG(current_execute_data) && !CG(in_compilation)) {
- zend_throw_exception_ex(NULL, 0, "Division by zero");
+ zend_error(E_ERROR | E_EXCEPTION, "Modulo by zero");
} else {
- zend_error_noreturn(E_ERROR, "Division by zero");
+ zend_error_noreturn(E_ERROR, "Modulo by zero");
}
ZVAL_UNDEF(result);
return FAILURE;
- }
-
- if (op2_lval == -1) {
- /* Prevent overflow error/crash if op1==LONG_MIN */
+ } else if (UNEXPECTED(op2_lval == -1)) {
+ /* Prevent overflow error/crash if op1 == LONG_MIN */
ZVAL_LONG(result, 0);
- return SUCCESS;
+ } else {
+ ZVAL_LONG(result, op1_lval % op2_lval);
}
-
- ZVAL_LONG(result, op1_lval % op2_lval);
return SUCCESS;
}
/* }}} */