diff options
| author | Nikita Popov <nikic@php.net> | 2016-01-12 15:18:10 +0100 |
|---|---|---|
| committer | Nikita Popov <nikic@php.net> | 2016-01-12 15:37:39 +0100 |
| commit | 35662c9bd3d88924ccf4683ff5fa2c710bb2b04b (patch) | |
| tree | bc6cfd2db6567147c361661e3b1e69c755e89529 | |
| parent | 65e592e4770c0dba275fc3a600cc59fa09a0d878 (diff) | |
| download | php-git-35662c9bd3d88924ccf4683ff5fa2c710bb2b04b.tar.gz | |
Forbid double use() and use() of param
Also commit a test I forgot to add for forbidden use() of
auto-globals.
| -rw-r--r-- | Zend/tests/closure_use_auto_global.phpt | 16 | ||||
| -rw-r--r-- | Zend/tests/closure_use_parameter_name.phpt | 14 | ||||
| -rw-r--r-- | Zend/tests/closure_use_variable_twice.phpt | 15 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 22 |
4 files changed, 65 insertions, 2 deletions
diff --git a/Zend/tests/closure_use_auto_global.phpt b/Zend/tests/closure_use_auto_global.phpt new file mode 100644 index 0000000000..9ab0897e12 --- /dev/null +++ b/Zend/tests/closure_use_auto_global.phpt @@ -0,0 +1,16 @@ +--TEST-- +Cannot use() auto-global +--FILE-- +<?php + +function test() { + $fn = function() use($GLOBALS) { + var_dump($GLOBALS); + }; + $fn(); +} +test(); + +?> +--EXPECTF-- +Fatal error: Cannot use auto-global as lexical variable in %s on line %d diff --git a/Zend/tests/closure_use_parameter_name.phpt b/Zend/tests/closure_use_parameter_name.phpt new file mode 100644 index 0000000000..7ecc6d8dd1 --- /dev/null +++ b/Zend/tests/closure_use_parameter_name.phpt @@ -0,0 +1,14 @@ +--TEST-- +Can't use name of lexical variable for parameter +--FILE-- +<?php + +$a = 1; +$fn = function ($a) use ($a) { + var_dump($a); +}; +$fn(2); + +?> +--EXPECTF-- +Fatal error: Cannot use lexical variable $a as a parameter name in %s on line %d diff --git a/Zend/tests/closure_use_variable_twice.phpt b/Zend/tests/closure_use_variable_twice.phpt new file mode 100644 index 0000000000..06c2645809 --- /dev/null +++ b/Zend/tests/closure_use_variable_twice.phpt @@ -0,0 +1,15 @@ +--TEST-- +Closure cannot use one variable twice +--FILE-- +<?php + +$a = 1; +$fn = function() use ($a, &$a) { + $a = 2; +}; +$fn(); +var_dump($a); + +?> +--EXPECTF-- +Fatal error: Cannot use variable $a twice in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2cc1a640aa..8ac9819135 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3725,7 +3725,7 @@ void zend_compile_global_var(zend_ast *ast) /* {{{ */ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_bool by_ref) /* {{{ */ { - znode var_node, result; + znode var_node; zend_op *opline; zend_compile_expr(&var_node, var_ast); @@ -4923,15 +4923,33 @@ static void zend_compile_closure_binding(znode *closure, zend_ast *uses_ast) /* void zend_compile_closure_uses(zend_ast *ast) /* {{{ */ { + zend_op_array *op_array = CG(active_op_array); zend_ast_list *list = zend_ast_get_list(ast); uint32_t i; for (i = 0; i < list->children; ++i) { zend_ast *var_ast = list->child[i]; + zend_string *var_name = zend_ast_get_str(var_ast); zend_bool by_ref = var_ast->attr; - zval zv; ZVAL_NULL(&zv); + + if (op_array->static_variables + && zend_hash_exists(op_array->static_variables, var_name)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use variable $%s twice", ZSTR_VAL(var_name)); + } + + { + int i; + for (i = 0; i < op_array->last_var; i++) { + if (zend_string_equals(op_array->vars[i], var_name)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot use lexical variable $%s as a parameter name", ZSTR_VAL(var_name)); + } + } + } + zend_compile_static_var_common(var_ast, &zv, by_ref); } } |
