diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2014-04-11 18:21:46 +0200 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2014-04-11 18:21:46 +0200 |
commit | ee2a7c7d41ec98c7529b46583f49e0936cac8774 (patch) | |
tree | 9f7cc94cac8354597b4143f234635ee59e6bc58c | |
parent | ad05d3898eae472532620ce9623c9d39c23ef16a (diff) | |
download | php-git-ee2a7c7d41ec98c7529b46583f49e0936cac8774.tar.gz |
Fixed disallowal of array usage in constants at run-time
Added at the same time the possibility of array dereferencing
to complete the set of features (useful application of arrays in constants)
-rw-r--r-- | Zend/tests/bug66015.phpt | 2 | ||||
-rw-r--r-- | Zend/tests/errmsg_040.phpt | 6 | ||||
-rw-r--r-- | Zend/tests/ns_059.phpt | 7 | ||||
-rw-r--r-- | Zend/zend_ast.c | 12 | ||||
-rw-r--r-- | Zend/zend_execute.c | 8 | ||||
-rw-r--r-- | Zend/zend_execute.h | 2 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 3 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 17 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 51 |
9 files changed, 62 insertions, 46 deletions
diff --git a/Zend/tests/bug66015.phpt b/Zend/tests/bug66015.phpt index f1cbd37aec..4f6d51e0dd 100644 --- a/Zend/tests/bug66015.phpt +++ b/Zend/tests/bug66015.phpt @@ -22,11 +22,9 @@ class Test $test = new Test(); ?> -===DONE=== --EXPECTF-- array ( 1 => 'first', 2 => 'second', 3 => 'third', ) -===DONE=== diff --git a/Zend/tests/errmsg_040.phpt b/Zend/tests/errmsg_040.phpt index 2b192d0b83..c3a007f8c1 100644 --- a/Zend/tests/errmsg_040.phpt +++ b/Zend/tests/errmsg_040.phpt @@ -1,7 +1,5 @@ --TEST-- errmsg: arrays are not allowed in class constants ---XFAIL-- -Actually it's hard to test where the array comes from (property, constant, ...) --FILE-- <?php @@ -9,7 +7,9 @@ class test { const TEST = array(1,2,3); } +var_dump(test::TEST); + echo "Done\n"; ?> --EXPECTF-- -Fatal error: Arrays are not allowed in class constants in %s on line %d +Fatal error: Arrays are not allowed in constants at run-time in %s on line %d diff --git a/Zend/tests/ns_059.phpt b/Zend/tests/ns_059.phpt index b9fcfee5c0..48da40b3f6 100644 --- a/Zend/tests/ns_059.phpt +++ b/Zend/tests/ns_059.phpt @@ -1,10 +1,11 @@ --TEST-- 059: Constant arrays ---XFAIL-- -Actually it's hard to test where the array comes from (property, constant, ...) --FILE-- <?php const C = array(); + +var_dump(C); +?> --EXPECTF-- -Fatal error: Arrays are not allowed as constants in %sns_059.php on line 2 +Fatal error: Arrays are not allowed in constants at run-time in %sns_059.php on line 4 diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index 8a3df98c10..fa32232516 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -322,6 +322,18 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s } } break; + case ZEND_FETCH_DIM_R: + zend_ast_evaluate(&op1, (&ast->u.child)[0], scope TSRMLS_CC); + zend_ast_evaluate(&op2, (&ast->u.child)[1], scope TSRMLS_CC); + { + zval *tmp; + zend_fetch_dimension_by_zval(&tmp, &op1, &op2 TSRMLS_CC); + *result = *tmp; + efree(tmp); + } + zval_dtor(&op1); + zval_dtor(&op2); + break; default: zend_error(E_ERROR, "Unsupported constant expression"); } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 66accd61e9..bdf8b6e70f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1352,9 +1352,15 @@ static void zend_fetch_dimension_address_read(temp_variable *result, zval *conta } } +ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC) { + temp_variable tmp; + zend_fetch_dimension_address_read(&tmp, container, dim, IS_TMP_VAR, BP_VAR_R TSRMLS_CC); + *result = tmp.var.ptr; +} + static void zend_fetch_property_address(temp_variable *result, zval **container_ptr, zval *prop_ptr, const zend_literal *key, int type TSRMLS_DC) { - zval *container = *container_ptr;; + zval *container = *container_ptr; if (Z_TYPE_P(container) != IS_OBJECT) { if (container == &EG(error_zval)) { diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 0d3a908a15..179eacdf52 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -362,6 +362,8 @@ ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint class_n ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC); void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC); +ZEND_API void zend_fetch_dimension_by_zval(zval **result, zval *container, zval *dim TSRMLS_DC); + #ifdef ZEND_WIN32 void zend_init_timeout_thread(void); void zend_shutdown_timeout_thread(void); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 40e5c05bce..56e702e8f9 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -1003,7 +1003,8 @@ static_scalar_value: ; static_operation: - static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); } + static_scalar_value '[' static_scalar_value ']' { $$.u.ast = zend_ast_create_binary(ZEND_FETCH_DIM_R, $1.u.ast, $3.u.ast); } + | static_scalar_value '+' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_ADD, $1.u.ast, $3.u.ast); } | static_scalar_value '-' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_SUB, $1.u.ast, $3.u.ast); } | static_scalar_value '*' static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_MUL, $1.u.ast, $3.u.ast); } | static_scalar_value T_POW static_scalar_value { $$.u.ast = zend_ast_create_binary(ZEND_POW, $1.u.ast, $3.u.ast); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 08eb471d49..85e348c901 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3710,8 +3710,6 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) retval = &EX_T(opline->result.var).tmp_var; ZVAL_COPY_VALUE(retval, &c->value); zval_copy_ctor(retval); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } else { /* class constant */ zend_class_entry *ce; @@ -3722,8 +3720,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) value = CACHED_PTR(opline->op2.literal->cache_slot); ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } else if (CACHED_PTR(opline->op1.literal->cache_slot)) { ce = CACHED_PTR(opline->op1.literal->cache_slot); } else { @@ -3741,8 +3738,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } } @@ -3767,10 +3763,13 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) } else { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); } - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } +constant_fetch_end: + if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) { + zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time"); + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUSED|CV) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e0277725d6..ec665e75fd 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3971,8 +3971,6 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO retval = &EX_T(opline->result.var).tmp_var; ZVAL_COPY_VALUE(retval, &c->value); zval_copy_ctor(retval); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } else { /* class constant */ zend_class_entry *ce; @@ -3983,8 +3981,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO value = CACHED_PTR(opline->op2.literal->cache_slot); ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } else if (CACHED_PTR(opline->op1.literal->cache_slot)) { ce = CACHED_PTR(opline->op1.literal->cache_slot); } else { @@ -4002,8 +3999,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } } @@ -4028,10 +4024,13 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO } else { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); } - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } +constant_fetch_end: + if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) { + zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time"); + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -15921,8 +15920,6 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE retval = &EX_T(opline->result.var).tmp_var; ZVAL_COPY_VALUE(retval, &c->value); zval_copy_ctor(retval); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } else { /* class constant */ zend_class_entry *ce; @@ -15933,8 +15930,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE value = CACHED_PTR(opline->op2.literal->cache_slot); ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } else if (CACHED_PTR(opline->op1.literal->cache_slot)) { ce = CACHED_PTR(opline->op1.literal->cache_slot); } else { @@ -15952,8 +15948,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } } @@ -15978,10 +15973,13 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE } else { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); } - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } +constant_fetch_end: + if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) { + zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time"); + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -25534,8 +25532,6 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC retval = &EX_T(opline->result.var).tmp_var; ZVAL_COPY_VALUE(retval, &c->value); zval_copy_ctor(retval); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } else { /* class constant */ zend_class_entry *ce; @@ -25546,8 +25542,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC value = CACHED_PTR(opline->op2.literal->cache_slot); ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } else if (CACHED_PTR(opline->op1.literal->cache_slot)) { ce = CACHED_PTR(opline->op1.literal->cache_slot); } else { @@ -25565,8 +25560,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC if ((value = CACHED_POLYMORPHIC_PTR(opline->op2.literal->cache_slot, ce)) != NULL) { ZVAL_COPY_VALUE(&EX_T(opline->result.var).tmp_var, *value); zval_copy_ctor(&EX_T(opline->result.var).tmp_var); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + goto constant_fetch_end; } } @@ -25591,10 +25585,13 @@ static int ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC } else { zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv)); } - - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); } +constant_fetch_end: + if (Z_TYPE(EX_T(opline->result.var).tmp_var) == IS_ARRAY) { + zend_error_noreturn(E_ERROR, "Arrays are not allowed in constants at run-time"); + } + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static int ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) |