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)
This commit is contained in:
Bob Weinand 2014-04-11 18:21:46 +02:00
parent ad05d3898e
commit ee2a7c7d41
9 changed files with 63 additions and 47 deletions

View File

@ -22,11 +22,9 @@ class Test
$test = new Test();
?>
===DONE===
--EXPECTF--
array (
1 => 'first',
2 => 'second',
3 => 'third',
)
===DONE===

View File

@ -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

View File

@ -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();
--EXPECTF--
Fatal error: Arrays are not allowed as constants in %sns_059.php on line 2
var_dump(C);
?>
--EXPECTF--
Fatal error: Arrays are not allowed in constants at run-time in %sns_059.php on line 4

View File

@ -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");
}

View File

@ -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)) {

View File

@ -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);

View File

@ -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); }

View File

@ -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)

View File

@ -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)