summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2018-12-16 13:30:11 +0100
committerChristoph M. Becker <cmbecker69@gmx.de>2018-12-16 13:30:11 +0100
commit0061db5503497458a85c40fb6bf1e2da80e7a036 (patch)
treee3fe633baef2ab537aa267eeb20bd4cc9be844c0
parent54739c7e662d3c617ce08680f8447ae4e98c6a04 (diff)
downloadphp-git-0061db5503497458a85c40fb6bf1e2da80e7a036.tar.gz
Fix #77291: magic methods inherited from a trait may be ignored
When adding methods from a trait, we must not assume that a method name with the same length as the name of the using class is either a PHP 4 style constructor, or not a magic method at all – it may well be another magic method. We mostly preserve the spirit of the optimization which caused this regression, and avoid string comparisons for all method names which can never be magic methods.
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug77291.phpt42
-rw-r--r--Zend/zend_inheritance.c24
3 files changed, 56 insertions, 12 deletions
diff --git a/NEWS b/NEWS
index b9a221bd21..ddfdb44d6c 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ PHP NEWS
(Valentin V. Bartenev)
. Fixed bug #76046 (PHP generates "FE_FREE" opcode on the wrong line).
(Nikita)
+ . Fixed bug #77291 (magic methods inherited from a trait may be ignored).
+ (cmb)
- CURL:
. Fixed bug #77264 (curl_getinfo returning microseconds, not seconds).
diff --git a/Zend/tests/bug77291.phpt b/Zend/tests/bug77291.phpt
new file mode 100644
index 0000000000..2960648a7c
--- /dev/null
+++ b/Zend/tests/bug77291.phpt
@@ -0,0 +1,42 @@
+--TEST--
+Bug #77291 (magic methods inherited from a trait may be ignored)
+--FILE--
+<?php
+
+trait AccessibleProperties
+{
+ public function __isset($property)
+ {
+ return property_exists($this, $property);
+ }
+
+ public function __get($property)
+ {
+ if (property_exists($this, $property)) {
+ return $this->$property;
+ }
+ }
+}
+
+class Foo4567 {
+ use AccessibleProperties;
+
+ protected $a = 'Some value';
+}
+
+class Foo45 {
+ use AccessibleProperties;
+
+ protected $a = 'Some value';
+}
+
+$foo = new Foo4567;
+var_dump(isset($foo->a));
+$foo = new Foo45;
+var_dump($foo->a);
+?>
+===DONE===
+--EXPECT--
+bool(true)
+string(10) "Some value"
+===DONE===
diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c
index 3a1497da7b..f3b62ef7e5 100644
--- a/Zend/zend_inheritance.c
+++ b/Zend/zend_inheritance.c
@@ -1126,18 +1126,7 @@ static zend_bool zend_traits_method_compatibility_check(zend_function *fn, zend_
static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zend_function* fe) /* {{{ */
{
- if (ZSTR_LEN(ce->name) == ZSTR_LEN(mname)) {
- zend_string *lowercase_name = zend_string_tolower(ce->name);
- lowercase_name = zend_new_interned_string(lowercase_name);
- if (!memcmp(ZSTR_VAL(mname), ZSTR_VAL(lowercase_name), ZSTR_LEN(mname))) {
- if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) {
- zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name));
- }
- ce->constructor = fe;
- fe->common.fn_flags |= ZEND_ACC_CTOR;
- }
- zend_string_release_ex(lowercase_name, 0);
- } else if (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_') {
+ if (ZSTR_LEN(ce->name) != ZSTR_LEN(mname) && (ZSTR_VAL(mname)[0] != '_' || ZSTR_VAL(mname)[1] != '_')) {
/* pass */
} else if (zend_string_equals_literal(mname, ZEND_CLONE_FUNC_NAME)) {
ce->clone = fe;
@@ -1168,6 +1157,17 @@ static void zend_add_magic_methods(zend_class_entry* ce, zend_string* mname, zen
ce->__tostring = fe;
} else if (zend_string_equals_literal(mname, ZEND_DEBUGINFO_FUNC_NAME)) {
ce->__debugInfo = fe;
+ } else if (ZSTR_LEN(ce->name) == ZSTR_LEN(mname)) {
+ zend_string *lowercase_name = zend_string_tolower(ce->name);
+ lowercase_name = zend_new_interned_string(lowercase_name);
+ if (!memcmp(ZSTR_VAL(mname), ZSTR_VAL(lowercase_name), ZSTR_LEN(mname))) {
+ if (ce->constructor && (!ce->parent || ce->constructor != ce->parent->constructor)) {
+ zend_error_noreturn(E_COMPILE_ERROR, "%s has colliding constructor definitions coming from traits", ZSTR_VAL(ce->name));
+ }
+ ce->constructor = fe;
+ fe->common.fn_flags |= ZEND_ACC_CTOR;
+ }
+ zend_string_release_ex(lowercase_name, 0);
}
}
/* }}} */