diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2015-06-28 18:22:10 +0200 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2015-06-28 18:22:59 +0200 |
commit | fb08798c9f0ea820d567668d0cea4833dc61dd8e (patch) | |
tree | f8a0be22eb7e68f2b244d994120d54544b40e1d1 /Zend/zend_operators.c | |
parent | 64c371142cbdb82eb0879d247430797d73a8ac2d (diff) | |
download | php-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.c | 54 |
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; } /* }}} */ |