diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-04-02 02:05:25 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-04-02 02:05:25 +0300 |
commit | ea09a9fa325fe21ebc81c41a63ab8c2f377d7f75 (patch) | |
tree | 333736f85df668e9cba95ee567a59d3e889260c3 /Zend/zend_ast.c | |
parent | 956fa034e3b9de643153fd83fd63d36547bfa821 (diff) | |
download | php-git-ea09a9fa325fe21ebc81c41a63ab8c2f377d7f75.tar.gz |
Convert fatal errors into EngineExceptions
Make zval_update_constant_ex(), zval_update_constant(), zend_update_class_constants() and zend_ast_evaluate() return SUCCESS or FAILURE.
Diffstat (limited to 'Zend/zend_ast.c')
-rw-r--r-- | Zend/zend_ast.c | 172 |
1 files changed, 118 insertions, 54 deletions
diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index b8a2d45474..d538a2191f 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -177,7 +177,7 @@ ZEND_API zend_ast *zend_ast_list_add(zend_ast *ast, zend_ast *op) { return (zend_ast *) list; } -static void zend_ast_add_array_element(zval *result, zval *offset, zval *expr) +static int zend_ast_add_array_element(zval *result, zval *offset, zval *expr) { switch (Z_TYPE_P(offset)) { case IS_UNDEF: @@ -203,68 +203,90 @@ static void zend_ast_add_array_element(zval *result, zval *offset, zval *expr) zend_hash_index_update(Z_ARRVAL_P(result), zend_dval_to_lval(Z_DVAL_P(offset)), expr); break; default: - zend_error_noreturn(E_ERROR, "Illegal offset type"); - break; + zend_error(E_EXCEPTION | E_ERROR, "Illegal offset type"); + return FAILURE; } + return SUCCESS; } -ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) +ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *scope) { zval op1, op2; + int ret = SUCCESS; switch (ast->kind) { case ZEND_AST_BINARY_OP: - { - binary_op_type op = get_binary_op(ast->attr); - zend_ast_evaluate(&op1, ast->child[0], scope); - zend_ast_evaluate(&op2, ast->child[1], scope); - op(result, &op1, &op2); - zval_dtor(&op1); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + } else { + binary_op_type op = get_binary_op(ast->attr); + ret = op(result, &op1, &op2); + zval_dtor(&op1); + zval_dtor(&op2); + } break; - } case ZEND_AST_GREATER: case ZEND_AST_GREATER_EQUAL: - { - /* op1 > op2 is the same as op2 < op1 */ - binary_op_type op = ast->kind == ZEND_AST_GREATER - ? is_smaller_function : is_smaller_or_equal_function; - zend_ast_evaluate(&op1, ast->child[0], scope); - zend_ast_evaluate(&op2, ast->child[1], scope); - op(result, &op2, &op1); - zval_dtor(&op1); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + } else { + /* op1 > op2 is the same as op2 < op1 */ + binary_op_type op = ast->kind == ZEND_AST_GREATER + ? is_smaller_function : is_smaller_or_equal_function; + ret = op(result, &op2, &op1); + zval_dtor(&op1); + zval_dtor(&op2); + } break; - } case ZEND_AST_UNARY_OP: - { - unary_op_type op = get_unary_op(ast->attr); - zend_ast_evaluate(&op1, ast->child[0], scope); - op(result, &op1); - zval_dtor(&op1); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else { + unary_op_type op = get_unary_op(ast->attr); + ret = op(result, &op1); + zval_dtor(&op1); + } break; - } case ZEND_AST_ZVAL: { zval *zv = zend_ast_get_zval(ast); if (scope) { /* class constants may be updated in-place */ if (Z_OPT_CONSTANT_P(zv)) { - zval_update_constant_ex(zv, 1, scope); + if (UNEXPECTED(zval_update_constant_ex(zv, 1, scope) != SUCCESS)) { + ret = FAILURE; + break; + } } ZVAL_DUP(result, zv); } else { ZVAL_DUP(result, zv); if (Z_OPT_CONSTANT_P(result)) { - zval_update_constant_ex(result, 1, scope); + if (UNEXPECTED(zval_update_constant_ex(result, 1, scope) != SUCCESS)) { + ret = FAILURE; + break; + } } } break; } case ZEND_AST_AND: - zend_ast_evaluate(&op1, ast->child[0], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + break; + } if (zend_is_true(&op1)) { - zend_ast_evaluate(&op2, ast->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } ZVAL_BOOL(result, zend_is_true(&op2)); zval_dtor(&op2); } else { @@ -273,41 +295,65 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s zval_dtor(&op1); break; case ZEND_AST_OR: - zend_ast_evaluate(&op1, ast->child[0], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + break; + } if (zend_is_true(&op1)) { ZVAL_TRUE(result); } else { - zend_ast_evaluate(&op2, ast->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } ZVAL_BOOL(result, zend_is_true(&op2)); zval_dtor(&op2); } zval_dtor(&op1); break; case ZEND_AST_CONDITIONAL: - zend_ast_evaluate(&op1, ast->child[0], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + break; + } if (zend_is_true(&op1)) { if (!ast->child[1]) { *result = op1; } else { - zend_ast_evaluate(result, ast->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(result, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } zval_dtor(&op1); } } else { - zend_ast_evaluate(result, ast->child[2], scope); + if (UNEXPECTED(zend_ast_evaluate(result, ast->child[2], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + break; + } zval_dtor(&op1); } break; case ZEND_AST_UNARY_PLUS: - ZVAL_LONG(&op1, 0); - zend_ast_evaluate(&op2, ast->child[0], scope); - add_function(result, &op1, &op2); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else { + ZVAL_LONG(&op1, 0); + ret = add_function(result, &op1, &op2); + zval_dtor(&op2); + } break; case ZEND_AST_UNARY_MINUS: - ZVAL_LONG(&op1, 0); - zend_ast_evaluate(&op2, ast->child[0], scope); - sub_function(result, &op1, &op2); - zval_dtor(&op2); + if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else { + ZVAL_LONG(&op1, 0); + ret = sub_function(result, &op1, &op2); + zval_dtor(&op2); + } break; case ZEND_AST_ARRAY: array_init(result); @@ -317,29 +363,47 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s for (i = 0; i < list->children; i++) { zend_ast *elem = list->child[i]; if (elem->child[1]) { - zend_ast_evaluate(&op1, elem->child[1], scope); + if (UNEXPECTED(zend_ast_evaluate(&op1, elem->child[1], scope) != SUCCESS)) { + zval_dtor(result); + return FAILURE; + } } else { ZVAL_UNDEF(&op1); } - zend_ast_evaluate(&op2, elem->child[0], scope); - zend_ast_add_array_element(result, &op1, &op2); + if (UNEXPECTED(zend_ast_evaluate(&op2, elem->child[0], scope) != SUCCESS)) { + zval_dtor(&op1); + zval_dtor(result); + return FAILURE; + } + if (UNEXPECTED(zend_ast_add_array_element(result, &op1, &op2) != SUCCESS)) { + zval_dtor(&op1); + zval_dtor(&op2); + zval_dtor(result); + return FAILURE; + } } } break; case ZEND_AST_DIM: - zend_ast_evaluate(&op1, ast->child[0], scope); - zend_ast_evaluate(&op2, ast->child[1], scope); - { + if (UNEXPECTED(zend_ast_evaluate(&op1, ast->child[0], scope) != SUCCESS)) { + ret = FAILURE; + } else if (UNEXPECTED(zend_ast_evaluate(&op2, ast->child[1], scope) != SUCCESS)) { + zval_dtor(&op1); + ret = FAILURE; + } else { zval tmp; + zend_fetch_dimension_by_zval(&tmp, &op1, &op2); ZVAL_ZVAL(result, &tmp, 1, 1); + zval_dtor(&op1); + zval_dtor(&op2); } - zval_dtor(&op1); - zval_dtor(&op2); break; default: - zend_error_noreturn(E_ERROR, "Unsupported constant expression"); + zend_error(E_EXCEPTION | E_ERROR, "Unsupported constant expression"); + ret = FAILURE; } + return ret; } ZEND_API zend_ast *zend_ast_copy(zend_ast *ast) |