]> granicus.if.org Git - php/commitdiff
Disallow direct incdec of function return value
authorNikita Popov <nikic@php.net>
Fri, 27 Mar 2015 15:40:04 +0000 (16:40 +0100)
committerNikita Popov <nikic@php.net>
Fri, 27 Mar 2015 15:40:04 +0000 (16:40 +0100)
Matching PHP 5 behavior.

We may want to support this for by-reference returns, but that
requires implementing further checks.

Zend/tests/increment_function_return_error.phpt [new file with mode: 0644]
Zend/zend_compile.c

diff --git a/Zend/tests/increment_function_return_error.phpt b/Zend/tests/increment_function_return_error.phpt
new file mode 100644 (file)
index 0000000..329cc83
--- /dev/null
@@ -0,0 +1,14 @@
+--TEST--
+It's not possible to increment the return value of a function
+--FILE--
+<?php
+
+function test() {
+    return 42;
+}
+
+++test();
+
+?>
+--EXPECTF--
+Fatal error: Can't use function return value in write context in %s on line %d
index de8a89d51fb029b2ec9390e5c8dc232db76a7ac9..db733ed3cac51abb40aeb681a5a2ce22e5752218 100644 (file)
@@ -2343,7 +2343,7 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
 }
 /* }}} */
 
-void zend_ensure_writable_variable(const zend_ast *ast) /* {{{ */
+static void zend_ensure_writable_variable(const zend_ast *ast) /* {{{ */
 {
        if (ast->kind == ZEND_AST_CALL) {
                zend_error_noreturn(E_COMPILE_ERROR, "Can't use function return value in write context");
@@ -5648,6 +5648,8 @@ void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */
        zend_ast *var_ast = ast->child[0];
        ZEND_ASSERT(ast->kind == ZEND_AST_POST_INC || ast->kind == ZEND_AST_POST_DEC);
 
+       zend_ensure_writable_variable(var_ast);
+
        if (var_ast->kind == ZEND_AST_PROP) {
                zend_op *opline = zend_compile_prop_common(NULL, var_ast, BP_VAR_RW);
                opline->opcode = ast->kind == ZEND_AST_POST_INC ? ZEND_POST_INC_OBJ : ZEND_POST_DEC_OBJ;
@@ -5666,6 +5668,8 @@ void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */
        zend_ast *var_ast = ast->child[0];
        ZEND_ASSERT(ast->kind == ZEND_AST_PRE_INC || ast->kind == ZEND_AST_PRE_DEC);
 
+       zend_ensure_writable_variable(var_ast);
+
        if (var_ast->kind == ZEND_AST_PROP) {
                zend_op *opline = zend_compile_prop_common(result, var_ast, BP_VAR_RW);
                opline->opcode = ast->kind == ZEND_AST_PRE_INC ? ZEND_PRE_INC_OBJ : ZEND_PRE_DEC_OBJ;