From 220641af7061fd77b1e4cf90f6bbdc83514eba14 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 2 Oct 2007 08:26:50 +0000 Subject: [PATCH] Fixed bug #42819 (namespaces in indexes of constant arrays) --- NEWS | 1 + Zend/tests/bug42819.phpt | 282 +++++++++++++++++++++++++++++++++++++++ Zend/zend.h | 1 + Zend/zend_compile.c | 1 + Zend/zend_execute_API.c | 2 +- Zend/zend_vm_def.h | 2 +- Zend/zend_vm_execute.h | 6 +- 7 files changed, 290 insertions(+), 5 deletions(-) create mode 100755 Zend/tests/bug42819.phpt diff --git a/NEWS b/NEWS index 77a50ea62f1..1ea76e9a638 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,7 @@ PHP NEWS - Improved and cleaned CGI code. FastCGI is now always enabled and can not be disabled. See sapi/cgi/CHANGES for more details. (Dmitry) +- Fixed bug #42819 (namespaces in indexes of constant arrays). (Dmitry) - Fixed bug #42802 (Namespace not supported in typehints). (Dmitry) - Fixed bug #42798 (__autoload() not triggered for classes used in method signature). (Dmitry) diff --git a/Zend/tests/bug42819.phpt b/Zend/tests/bug42819.phpt new file mode 100755 index 00000000000..812c26bfc9f --- /dev/null +++ b/Zend/tests/bug42819.phpt @@ -0,0 +1,282 @@ +--TEST-- +Bug #42819 (namespaces in indexes of constant arrays) +--FILE-- + 0); + static $a2 = array(foo::I => 0); + static $a3 = array(foo::foo::I => 0); + static $a4 = array(::foo::I => 0); + static $a5 = array(::foo::foo::I => 0); + static $a6 = array(ArrayObject::STD_PROP_LIST => 0); + static $a7 = array(E_ERROR => 0); +} + +class bar2 { + static $a1 = array(I => I); + static $a2 = array(foo::I => I); + static $a3 = array(foo::foo::I => I); + static $a4 = array(::foo::I => I); + static $a5 = array(::foo::foo::I => I); + static $a6 = array(ArrayObject::STD_PROP_LIST => I); + static $a7 = array(E_ERROR => I); +} + +class bar3 { + static $a1 = array(I => foo::I); + static $a2 = array(foo::I => foo::I); + static $a3 = array(foo::foo::I => foo::I); + static $a4 = array(::foo::I => foo::I); + static $a5 = array(::foo::foo::I => foo::I); + static $a6 = array(ArrayObject::STD_PROP_LIST => foo::I); + static $a7 = array(E_ERROR => foo::I); +} + +class bar4 { + static $a1 = array(I => ArrayObject::STD_PROP_LIST); + static $a2 = array(foo::I => ArrayObject::STD_PROP_LIST); + static $a3 = array(foo::foo::I => ArrayObject::STD_PROP_LIST); + static $a4 = array(::foo::I => ArrayObject::STD_PROP_LIST); + static $a5 = array(::foo::foo::I => ArrayObject::STD_PROP_LIST); + static $a6 = array(ArrayObject::STD_PROP_LIST => ArrayObject::STD_PROP_LIST); + static $a7 = array(E_ERROR => ArrayObject::STD_PROP_LIST); +} + +class bar5 { + static $a1 = array(I => E_ERROR); + static $a2 = array(foo::I => E_ERROR); + static $a3 = array(foo::foo::I => E_ERROR); + static $a4 = array(::foo::I => E_ERROR); + static $a5 = array(::foo::foo::I => E_ERROR); + static $a6 = array(ArrayObject::STD_PROP_LIST => E_ERROR); + static $a7 = array(E_ERROR => E_ERROR); +} + +echo C; +echo foo::C; +echo foo::foo::C; +echo ::foo::C; +echo ::foo::foo::C; +echo ArrayObject::STD_PROP_LIST . "\n"; +echo E_ERROR . "\n"; + +echo foo::foo::C1; +echo foo::foo::C2; +echo foo::foo::C3; +echo foo::foo::C4; +echo foo::foo::C5; +echo foo::foo::C6 . "\n"; +echo foo::foo::C7 . "\n"; + +print_r(bar1::$a1); +print_r(bar1::$a2); +print_r(bar1::$a3); +print_r(bar1::$a4); +print_r(bar1::$a5); +print_r(bar1::$a6); +print_r(bar1::$a7); + +print_r(bar2::$a1); +print_r(bar2::$a2); +print_r(bar2::$a3); +print_r(bar2::$a4); +print_r(bar2::$a5); +print_r(bar2::$a6); +print_r(bar2::$a7); + +print_r(bar3::$a1); +print_r(bar3::$a2); +print_r(bar3::$a3); +print_r(bar3::$a4); +print_r(bar3::$a5); +print_r(bar3::$a6); +print_r(bar3::$a7); + +print_r(bar4::$a1); +print_r(bar4::$a2); +print_r(bar4::$a3); +print_r(bar4::$a4); +print_r(bar4::$a5); +print_r(bar4::$a6); +print_r(bar4::$a7); + +print_r(bar5::$a1); +print_r(bar5::$a2); +print_r(bar5::$a3); +print_r(bar5::$a4); +print_r(bar5::$a5); +print_r(bar5::$a6); +print_r(bar5::$a7); +?> +--EXPECT-- +foo::C +foo::C +foo::foo::C +foo::C +foo::foo::C +1 +1 +foo::C +foo::C +foo::foo::C +foo::C +foo::foo::C +1 +1 +Array +( + [11] => 0 +) +Array +( + [11] => 0 +) +Array +( + [22] => 0 +) +Array +( + [11] => 0 +) +Array +( + [22] => 0 +) +Array +( + [1] => 0 +) +Array +( + [1] => 0 +) +Array +( + [11] => 11 +) +Array +( + [11] => 11 +) +Array +( + [22] => 11 +) +Array +( + [11] => 11 +) +Array +( + [22] => 11 +) +Array +( + [1] => 11 +) +Array +( + [1] => 11 +) +Array +( + [11] => 11 +) +Array +( + [11] => 11 +) +Array +( + [22] => 11 +) +Array +( + [11] => 11 +) +Array +( + [22] => 11 +) +Array +( + [1] => 11 +) +Array +( + [1] => 11 +) +Array +( + [11] => 1 +) +Array +( + [11] => 1 +) +Array +( + [22] => 1 +) +Array +( + [11] => 1 +) +Array +( + [22] => 1 +) +Array +( + [1] => 1 +) +Array +( + [1] => 1 +) +Array +( + [11] => 1 +) +Array +( + [11] => 1 +) +Array +( + [22] => 1 +) +Array +( + [11] => 1 +) +Array +( + [22] => 1 +) +Array +( + [1] => 1 +) +Array +( + [1] => 1 +) diff --git a/Zend/zend.h b/Zend/zend.h index 8afe53fda05..7246462fe7e 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -298,6 +298,7 @@ struct _zval_struct { zend_uint refcount; zend_uchar type; /* active type */ zend_uchar is_ref; + zend_uchar idx_type; /* type of element's index in constant array */ }; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 92f0be62905..ab86ce463f0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3640,6 +3640,7 @@ void zend_do_add_static_array_element(znode *result, znode *offset, znode *expr) case IS_CONSTANT: /* Ugly hack to denote that this value has a constant index */ Z_TYPE_P(element) |= IS_CONSTANT_INDEX; + element->idx_type = Z_TYPE(offset->u.constant); /* break missing intentionally */ case IS_STRING: zend_symtable_update(result->u.constant.value.ht, offset->u.constant.value.str.val, offset->u.constant.value.str.len+1, &element, sizeof(zval *), NULL); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1c636b552d9..f47b0af383b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -517,7 +517,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - if (!zend_get_constant_ex(str_index, str_index_len-1, &const_value, scope, 0 TSRMLS_CC)) { + if (!zend_get_constant_ex(str_index, str_index_len-1, &const_value, scope, (*element)->idx_type TSRMLS_CC)) { if ((colon = memchr(str_index, ':', str_index_len-1)) && colon[1] == ':') { zend_error(E_ERROR, "Undefined class constant '%s'", str_index); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 06bb6fe3e09..798a585960c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2681,7 +2681,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST) if (zend_hash_find(&ce->constants_table, Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) { if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - Z_TYPE_PP(value) == IS_CONSTANT) { + (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce; diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 46b8ca9cea7..3e5dfca60da 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2554,7 +2554,7 @@ static int ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (zend_hash_find(&ce->constants_table, Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) { if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - Z_TYPE_PP(value) == IS_CONSTANT) { + (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce; @@ -9762,7 +9762,7 @@ static int ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (zend_hash_find(&ce->constants_table, Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) { if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - Z_TYPE_PP(value) == IS_CONSTANT) { + (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce; @@ -16288,7 +16288,7 @@ static int ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG if (zend_hash_find(&ce->constants_table, Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant)+1, (void **) &value) == SUCCESS) { if (Z_TYPE_PP(value) == IS_CONSTANT_ARRAY || - Z_TYPE_PP(value) == IS_CONSTANT) { + (Z_TYPE_PP(value) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { zend_class_entry *old_scope = EG(scope); EG(scope) = ce;