diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2017-03-15 19:06:34 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2017-03-15 19:49:02 +0100 |
commit | 2bba4a0d7f6d5e5712d60bc1cf2119622d837e55 (patch) | |
tree | 8d77cb855c870ba1a1d058703c06eb646bc034d4 | |
parent | f3ab4c1a086b17daad7a8ecf34292fff6b9566ce (diff) | |
download | php-git-2bba4a0d7f6d5e5712d60bc1cf2119622d837e55.tar.gz |
Fix bug #69676
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | Zend/tests/bug69676_2.phpt | 22 | ||||
-rw-r--r-- | Zend/tests/bug69676_3.phpt | 69 | ||||
-rw-r--r-- | Zend/zend_API.c | 2 | ||||
-rw-r--r-- | Zend/zend_constants.c | 5 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 2 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 6 |
7 files changed, 101 insertions, 7 deletions
@@ -8,6 +8,8 @@ PHP NEWS USE_ZEND_ALLOC=0). (Nikita) . Fixed bug #73960 (Leak with instance method calling static method with referenced return). (Nikita) + . Fixed bug #69676 (Resolution of self::FOO in class constants not correct). + (Nikita) - Date: . Fixed bug #72096 (Swatch time value incorrect for dates before 1970). (mcq8) diff --git a/Zend/tests/bug69676_2.phpt b/Zend/tests/bug69676_2.phpt new file mode 100644 index 0000000000..6ec3d499e5 --- /dev/null +++ b/Zend/tests/bug69676_2.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #69676: Resolution of self::FOO in class constants not correct (variation) +--FILE-- +<?php + +class Foo { + const A = 'Foo::A'; + const B = self::A . ' and ' . self::C; + const C = 'Foo::C'; + +} + +class Bar extends Foo { + const A = 'Bar::A'; + const C = 'Bar::C'; +} + +var_dump(Bar::B); + +?> +--EXPECT-- +string(17) "Foo::A and Foo::C" diff --git a/Zend/tests/bug69676_3.phpt b/Zend/tests/bug69676_3.phpt new file mode 100644 index 0000000000..89f0090884 --- /dev/null +++ b/Zend/tests/bug69676_3.phpt @@ -0,0 +1,69 @@ +--TEST-- +Bug #69676: Resolution of self::FOO in class constants not correct (variation) +--FILE-- +<?php + +class P { + const N = 'P'; +} +class A extends P { + const selfN = self::N; + const parentN = parent::N; + const N = 'A'; +} +class B extends A { + const N = 'B'; +} + +var_dump(B::selfN); // A +var_dump(B::parentN); // P + +class A2 { + const selfN = self::N; + const N = 'A2'; +} +class B2 extends A2 { + const indSelfN = self::selfN; + const N = 'B2'; +} +class C2 extends B2 { + const N = 'C2'; +} + +var_dump(C2::indSelfN); // A2 + +class A3 { + const selfN = self::N; + const N = 'A3'; +} +class B3 extends A3 { + const exprSelfN = "expr" . self::selfN; + const N = 'B3'; +} +class C3 extends B3 { + const N = 'C3'; +} + +var_dump(C3::exprSelfN); // exprA3 + +class A4 { + const selfN = self::N; + const N = 'A4'; +} +class B4 extends A4 { + const N = 'B4'; + public $prop = self::selfN; +} +class C4 extends B4 { + const N = 'C4'; +} + +var_dump((new C4)->prop); // A4 + +?> +--EXPECT-- +string(1) "A" +string(1) "P" +string(2) "A2" +string(6) "exprA3" +string(2) "A4" diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 0cc4b51ec2..d73ad76fcb 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1132,7 +1132,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) { val = &c->value; if (Z_CONSTANT_P(val)) { - if (UNEXPECTED(zval_update_constant_ex(val, class_type) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) { return FAILURE; } } diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index cedf5fabc1..2f9d29d833 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -327,6 +327,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, size_t const_name_len = name_len - class_name_len - 2; zend_string *constant_name = zend_string_init(colon + 1, const_name_len, 0); zend_string *class_name = zend_string_init(name, class_name_len, 0); + zend_class_constant *c = NULL; zval *ret_constant = NULL; if (zend_string_equals_literal_ci(class_name, "self")) { @@ -355,7 +356,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, ce = zend_fetch_class(class_name, flags); } if (ce) { - zend_class_constant *c = zend_hash_find_ptr(&ce->constants_table, constant_name); + c = zend_hash_find_ptr(&ce->constants_table, constant_name); if (c == NULL) { if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) { zend_throw_error(NULL, "Undefined class constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name)); @@ -380,7 +381,7 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, } MARK_CONSTANT_VISITED(ret_constant); } - if (UNEXPECTED(zval_update_constant_ex(ret_constant, ce) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(ret_constant, c->ce) != SUCCESS)) { RESET_CONSTANT_VISITED(ret_constant); ret_constant = NULL; goto failure; diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 00b1301948..64dcdb623c 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5191,7 +5191,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO } value = &c->value; if (Z_CONSTANT_P(value)) { - zval_update_constant_ex(value, ce); + zval_update_constant_ex(value, c->ce); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 67107897f9..2bf932b47e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -5797,7 +5797,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS } value = &c->value; if (Z_CONSTANT_P(value)) { - zval_update_constant_ex(value, ce); + zval_update_constant_ex(value, c->ce); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -19985,7 +19985,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_ } value = &c->value; if (Z_CONSTANT_P(value)) { - zval_update_constant_ex(value, ce); + zval_update_constant_ex(value, c->ce); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -29790,7 +29790,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS } value = &c->value; if (Z_CONSTANT_P(value)) { - zval_update_constant_ex(value, ce); + zval_update_constant_ex(value, c->ce); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } |