diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-04-06 14:30:05 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-04-06 14:30:05 +0300 |
commit | cae0147ed3ceb55fcb1bc059b8e8ea6a36ea69a8 (patch) | |
tree | 4ca16379ac8d5cab749f07747e2599ee23a4d175 /Zend/zend_compile.c | |
parent | caf9219dea58dcc6ef6da2b3b86a1e9808363bff (diff) | |
download | php-git-cae0147ed3ceb55fcb1bc059b8e8ea6a36ea69a8.tar.gz |
Fixed weird operators behavior. Division by zero now emits warning and returns +/-INF, modulo by zero and intdid() throws an exception, shifts by negative offset throw exceptions. Compile-time evaluation of division by zero is disabled.
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 46 |
1 files changed, 40 insertions, 6 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 70359123c4..ac10a2ad74 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5538,12 +5538,30 @@ void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */ zend_compile_expr(&right_node, right_ast); if (left_node.op_type == IS_CONST && right_node.op_type == IS_CONST) { - result->op_type = IS_CONST; - zend_ct_eval_binary_op(&result->u.constant, opcode, - &left_node.u.constant, &right_node.u.constant); - zval_ptr_dtor(&left_node.u.constant); - zval_ptr_dtor(&right_node.u.constant); - return; + do { + /* don't evaluate divsion by zero at compile-time */ + if (opcode == ZEND_DIV) { + zval *op2 = &right_node.u.constant; + + convert_scalar_to_number(op2); + if (Z_TYPE_P(op2) == IS_LONG) { + if (Z_LVAL_P(op2) == 0) { + break; + } + } else if (Z_TYPE_P(op2) == IS_DOUBLE) { + if (Z_DVAL_P(op2) == 0.0) { + break; + } + } + } + + result->op_type = IS_CONST; + zend_ct_eval_binary_op(&result->u.constant, opcode, + &left_node.u.constant, &right_node.u.constant); + zval_ptr_dtor(&left_node.u.constant); + zval_ptr_dtor(&right_node.u.constant); + return; + } while (0); } do { @@ -6937,6 +6955,22 @@ void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */ return; } + /* don't evaluate divsion by zero at compile-time */ + if (ast->attr == ZEND_DIV) { + zval *op2 = zend_ast_get_zval(ast->child[1]); + + convert_scalar_to_number(op2); + if (Z_TYPE_P(op2) == IS_LONG) { + if (Z_LVAL_P(op2) == 0) { + return; + } + } else if (Z_TYPE_P(op2) == IS_DOUBLE) { + if (Z_DVAL_P(op2) == 0.0) { + return; + } + } + } + zend_ct_eval_binary_op(&result, ast->attr, zend_ast_get_zval(ast->child[0]), zend_ast_get_zval(ast->child[1])); break; |