]> granicus.if.org Git - php/commitdiff
Fix bug #65579 (Using traits with get_class_methods causes segfault).
authorAdam Harvey <aharvey@php.net>
Thu, 29 Aug 2013 03:33:42 +0000 (20:33 -0700)
committerAdam Harvey <aharvey@php.net>
Thu, 29 Aug 2013 03:33:42 +0000 (20:33 -0700)
Specifically, this checks if there are trait aliases defined in the class scope
before attempting to dereference the first trait alias. This handles the case
where a trait alias was used in a child trait but no aliases exist in the
concrete class.

NEWS
Zend/tests/bug65579.phpt [new file with mode: 0644]
Zend/zend_API.c

diff --git a/NEWS b/NEWS
index 093fa20626c8b5124904ea002e93fc85cc714eef..b718a74e45120713a31e86ab918e2c0ef4b53dc4 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP                                                                        NEWS
 ?? ??? 2013, PHP 5.4.20
 
 - Core:
+  . Fixed bug #65579 (Using traits with get_class_methods causes segfault).
+    (Adam)
   . Fixed bug #65490 (Duplicate calls to get lineno & filename for 
     DTRACE_FUNCTION_*). (Chris Jones)
   . Fixed bug #65483 (quoted-printable encode stream filter incorrectly encoding
diff --git a/Zend/tests/bug65579.phpt b/Zend/tests/bug65579.phpt
new file mode 100644 (file)
index 0000000..25d74ed
--- /dev/null
@@ -0,0 +1,29 @@
+--TEST--
+Bug #65579 (Using traits with get_class_methods causes segfault)
+--FILE--
+<?php
+trait ParentTrait {
+    public function testMethod() { }
+}
+
+trait ChildTrait {
+    use ParentTrait {
+        testMethod as testMethodFromParentTrait;
+    }
+    public function testMethod() { }
+}
+
+class TestClass {
+    use ChildTrait;
+}
+
+$obj = new TestClass();
+var_dump(get_class_methods($obj));
+?>
+--EXPECT--
+array(2) {
+  [0]=>
+  string(10) "testMethod"
+  [1]=>
+  string(25) "testmethodfromparenttrait"
+}
index 90d27b79878b74cc12cd0b22d4ac67be8358ff97..870a9b64801879bbb30cb7d595438115bbc6998e 100644 (file)
@@ -3917,15 +3917,16 @@ ZEND_API const char* zend_find_alias_name(zend_class_entry *ce, const char *name
 {
        zend_trait_alias *alias, **alias_ptr;
 
-       alias_ptr = ce->trait_aliases;
-       alias = *alias_ptr;
-       while (alias) {
-               if (alias->alias_len == len &&
-                   !strncasecmp(name, alias->alias, alias->alias_len)) {
-                       return alias->alias;
-               }
-               alias_ptr++;
+       if (alias_ptr = ce->trait_aliases) {
                alias = *alias_ptr;
+               while (alias) {
+                       if (alias->alias_len == len &&
+                               !strncasecmp(name, alias->alias, alias->alias_len)) {
+                               return alias->alias;
+                       }
+                       alias_ptr++;
+                       alias = *alias_ptr;
+               }
        }
 
        return name;