diff options
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; |