]> granicus.if.org Git - php/commitdiff
Fixed bug #78787
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 6 Nov 2019 11:51:25 +0000 (12:51 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 6 Nov 2019 11:52:34 +0000 (12:52 +0100)
Not the first time inheritance of shadow properties causes an issue,
thankfully this whole concept is gone in PHP 7.4.

NEWS
Zend/tests/bug78787.phpt [new file with mode: 0644]
Zend/zend_inheritance.c

diff --git a/NEWS b/NEWS
index f74a71fdcc90b5fb587382298ec324a645e15997..2e67e59683816beafd90b01abe014b5dce826008 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,10 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? ????, PHP 7.3.13
 
+- Core:
+  . Fixed bug #78787 (Segfault with trait overriding inherited private shadow
+    property). (Nikita)
+
 21 Nov 2019, PHP 7.3.12
 
 - Core:
diff --git a/Zend/tests/bug78787.phpt b/Zend/tests/bug78787.phpt
new file mode 100644 (file)
index 0000000..91d5a9a
--- /dev/null
@@ -0,0 +1,22 @@
+--TEST--
+Bug #78787: Segfault with trait overriding inherited private shadow property
+--FILE--
+<?php
+
+trait T {
+    private $prop;
+}
+class C1 {
+    /** Doc comment */
+    private $prop;
+}
+class C2 extends C1 {
+}
+class C3 extends C2 {
+    use T;
+}
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
index 0b0cb314b634d51d366954f04cf5a8eaf32449de..d271b741544c9a8dbada185802425b08af139b05 100644 (file)
@@ -1595,10 +1595,14 @@ static void zend_do_traits_property_binding(zend_class_entry *ce) /* {{{ */
                        /* next: check for conflicts with current class */
                        if ((coliding_prop = zend_hash_find_ptr(&ce->properties_info, prop_name)) != NULL) {
                                if (coliding_prop->flags & ZEND_ACC_SHADOW) {
-                                       zend_string_release_ex(coliding_prop->name, 0);
-                                       if (coliding_prop->doc_comment) {
-                                               zend_string_release_ex(coliding_prop->doc_comment, 0);
-                    }
+                                       /* Only free if shadow is coming from direct parent,
+                                        * otherwise these weren't copied in the first place. */
+                                       if (coliding_prop->ce == ce->parent) {
+                                               zend_string_release_ex(coliding_prop->name, 0);
+                                               if (coliding_prop->doc_comment) {
+                                                       zend_string_release_ex(coliding_prop->doc_comment, 0);
+                                               }
+                                       }
                                        zend_hash_del(&ce->properties_info, prop_name);
                                        flags |= ZEND_ACC_CHANGED;
                                } else {