--- /dev/null
+--TEST--
+Bug #3721 (Access to protected property of common base class)
+--FILE--
+<?php
+
+class A
+{
+ protected $value;
+
+ public function __construct($val)
+ {
+ $this->value = $val;
+ }
+
+ protected function getValue()
+ {
+ return $this->value;
+ }
+}
+
+class B extends A
+{
+ public function copyValue($obj)
+ {
+ $this->value = $obj->getValue();
+ $this->value = $obj->value; // value defined in common base class
+ }
+}
+class C extends A {}
+
+$B = new B("B");
+var_dump($B);
+$C = new C("C");
+var_dump($C);
+
+$B->copyValue($C);
+
+var_dump($B);
+
+?>
+===DONE===
+--EXPECTF--
+object(B)#%d (1) {
+ ["value":protected]=>
+ string(1) "B"
+}
+object(C)#%d (1) {
+ ["value":protected]=>
+ string(1) "C"
+}
+object(B)#%d (1) {
+ ["value":protected]=>
+ string(1) "C"
+}
+===DONE===
+--UEXPECTF--
+object(B)#%d (1) {
+ [u"value":protected]=>
+ unicode(1) "B"
+}
+object(C)#%d (1) {
+ [u"value":protected]=>
+ unicode(1) "C"
+}
+object(B)#%d (1) {
+ [u"value":protected]=>
+ unicode(1) "C"
+}
+===DONE===
property_info.doc_comment = doc_comment;
property_info.doc_comment_len = doc_comment_len;
+
+ property_info.ce = ce;
zend_u_hash_update(&ce->properties_info, type, name, name_length + 1, &property_info, sizeof(zend_property_info), NULL);
case ZEND_ACC_PUBLIC:
return 1;
case ZEND_ACC_PROTECTED:
- return zend_check_protected(ce, EG(scope));
+ return zend_check_protected(property_info->ce, EG(scope));
case ZEND_ACC_PRIVATE:
if (ce==EG(scope) && EG(scope)) {
return 1;
EG(std_property_info).name = Z_UNIVAL_P(member);
EG(std_property_info).name_length = Z_UNILEN_P(member);
EG(std_property_info).h = h;
+ EG(std_property_info).ce = ce;;
property_info = &EG(std_property_info);
}
return property_info;
std_property_info.name = property_name;
std_property_info.name_length = property_name_len;
std_property_info.h = zend_u_get_hash_value(UG(unicode)?IS_UNICODE:IS_STRING, std_property_info.name, std_property_info.name_length+1);
+ std_property_info.ce = ce;
property_info = &std_property_info;
}