summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2014-04-11 18:21:46 +0200
committerBob Weinand <bobwei9@hotmail.com>2014-04-11 18:21:46 +0200
commitee2a7c7d41ec98c7529b46583f49e0936cac8774 (patch)
tree9f7cc94cac8354597b4143f234635ee59e6bc58c
parentad05d3898eae472532620ce9623c9d39c23ef16a (diff)
downloadphp-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.phpt2
-rw-r--r--Zend/tests/errmsg_040.phpt6
-rw-r--r--Zend/tests/ns_059.phpt7
-rw-r--r--Zend/zend_ast.c12
-rw-r--r--Zend/zend_execute.c8
-rw-r--r--Zend/zend_execute.h2
-rw-r--r--Zend/zend_language_parser.y3
-rw-r--r--Zend/zend_vm_def.h17
-rw-r--r--Zend/zend_vm_execute.h51
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)