com php-src: Fix bug #69676: NEWS Zend/tests/bug69676 _2.phpt Zend/tests/bug69676_3.phpt Ze nd/zend_API.c Zend/zend_constants.c Zend/zend_vm _def.h Zend/zend_vm_execute.h

[email protected] (Nikita Popov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    2bba4a0d7f6d5e5712d60bc1cf2119622d837e55
Author:    Nikita Popov <[email protected]>         Wed, 15 Mar 2017 19:06:34 +0100
Parents:   f3ab4c1a086b17daad7a8ecf34292fff6b9566ce
Branches:  PHP-7.1 master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=2bba4a0d7f6d5e5712d60bc1cf2119622d837e55

Log:
Fix bug #69676

Bugs:
https://bugs.php.net/69676

Changed paths:
  M  NEWS
  A  Zend/tests/bug69676_2.phpt
  A  Zend/tests/bug69676_3.phpt
  M  Zend/zend_API.c
  M  Zend/zend_constants.c
  M  Zend/zend_vm_def.h
  M  Zend/zend_vm_execute.h


Diff:
diff --git a/NEWS b/NEWS
index 8fce4e9..af21109 100644
--- a/NEWS
+++ b/NEWS
@@ -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 0000000..6ec3d49
--- /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 0000000..89f0090
--- /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 0cc4b51..d73ad76 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 cedf5fa..2f9d29d 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 00b1301..64dcdb6 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 6710789..2bf932b 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();
 				}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.