mirror of
https://github.com/php/php-src.git
synced 2025-08-16 14:08:47 +02:00
Get rid if ZEND_ACC_SHADOW
This commit is contained in:
parent
b1f65fb25b
commit
d6c3f098b6
8 changed files with 189 additions and 117 deletions
|
@ -3,7 +3,7 @@ PHP 7.4 INTERNALS UPGRADE NOTES
|
||||||
1. Internal API changes
|
1. Internal API changes
|
||||||
a. php_sys_symlink() and php_sys_link()
|
a. php_sys_symlink() and php_sys_link()
|
||||||
b. zend_lookup_class_ex() and zend_fetch_class_by_name()
|
b. zend_lookup_class_ex() and zend_fetch_class_by_name()
|
||||||
c. Function flags
|
c. Function/property flags
|
||||||
|
|
||||||
2. Build system changes
|
2. Build system changes
|
||||||
a. Unix build system changes
|
a. Unix build system changes
|
||||||
|
@ -23,12 +23,16 @@ PHP 7.4 INTERNALS UPGRADE NOTES
|
||||||
changed to accept optional lower-case class name as zend_string*,
|
changed to accept optional lower-case class name as zend_string*,
|
||||||
instead of zval*.
|
instead of zval*.
|
||||||
|
|
||||||
c. Function flags changes
|
c. Function/property flags changes
|
||||||
- ZEND_ACC_CTOR and ZEND_ACC_DTOR are removed. It's possible to check if
|
- ZEND_ACC_CTOR and ZEND_ACC_DTOR are removed. It's possible to check if
|
||||||
method is a constructor/destructor using the following condition
|
method is a constructor/destructor using the following condition
|
||||||
(func->commpon.scope->constructor == func).
|
(func->commpon.scope->constructor == func).
|
||||||
- ZEND_ACC_IMPLEMENTED_ABSTRACT is removed (it was used only internally
|
- ZEND_ACC_IMPLEMENTED_ABSTRACT is removed (it was used only internally
|
||||||
during inheritance).
|
during inheritance).
|
||||||
|
- ZEND_ACC_IMPLEMENTED_ABSTRACT is removed (it was used only internally
|
||||||
|
- ZEND_ACC_SHADOW property flag is removed. Instead of creating shadow
|
||||||
|
clone, now we use the same private propert_info, and should also
|
||||||
|
check property_info->ce (in the same way as with methods).
|
||||||
|
|
||||||
========================
|
========================
|
||||||
2. Build system changes
|
2. Build system changes
|
||||||
|
|
|
@ -27,7 +27,7 @@ $b = new C;
|
||||||
$b->bar();
|
$b->bar();
|
||||||
?>
|
?>
|
||||||
--EXPECTF--
|
--EXPECTF--
|
||||||
Fatal error: Uncaught Error: Cannot access property B::$x in %sbug70873.php:%d
|
Fatal error: Uncaught Error: Cannot access private property B::$x in %sbug70873.php:%d
|
||||||
Stack trace:
|
Stack trace:
|
||||||
#0 %sbug70873.php(%d): B->bar()
|
#0 %sbug70873.php(%d): B->bar()
|
||||||
#1 {main}
|
#1 {main}
|
||||||
|
|
|
@ -1097,13 +1097,11 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st
|
||||||
zend_string *key;
|
zend_string *key;
|
||||||
|
|
||||||
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
|
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
|
||||||
if (((prop_info->flags & ZEND_ACC_SHADOW) &&
|
if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
|
||||||
prop_info->ce != scope) ||
|
|
||||||
((prop_info->flags & ZEND_ACC_PROTECTED) &&
|
|
||||||
!zend_check_protected(prop_info->ce, scope)) ||
|
!zend_check_protected(prop_info->ce, scope)) ||
|
||||||
((prop_info->flags & ZEND_ACC_PRIVATE) &&
|
((prop_info->flags & ZEND_ACC_PRIVATE) &&
|
||||||
ce != scope &&
|
prop_info->ce != scope &&
|
||||||
prop_info->ce != scope)) {
|
(ce != scope || prop_info->ce != ce))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
prop = NULL;
|
prop = NULL;
|
||||||
|
@ -1403,8 +1401,10 @@ ZEND_FUNCTION(property_exists)
|
||||||
RETURN_NULL();
|
RETURN_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((property_info = zend_hash_find_ptr(&ce->properties_info, property)) != NULL
|
property_info = zend_hash_find_ptr(&ce->properties_info, property);
|
||||||
&& (property_info->flags & ZEND_ACC_SHADOW) == 0) {
|
if (property_info != NULL
|
||||||
|
&& (!(property_info->flags & ZEND_ACC_PRIVATE)
|
||||||
|
|| property_info->ce == ce)) {
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,9 +218,6 @@ typedef struct _zend_oparray_context {
|
||||||
/* TODO: used only by ext/reflection ??? | | | */
|
/* TODO: used only by ext/reflection ??? | | | */
|
||||||
#define ZEND_ACC_IMPLICIT_PUBLIC (1 << 12) /* | ? | ? | ? */
|
#define ZEND_ACC_IMPLICIT_PUBLIC (1 << 12) /* | ? | ? | ? */
|
||||||
/* | | | */
|
/* | | | */
|
||||||
/* Shadow of parent's private method/property | | | */
|
|
||||||
#define ZEND_ACC_SHADOW (1 << 17) /* | ? | X | */
|
|
||||||
/* | | | */
|
|
||||||
/* Class Flags (unused: 0, 1, 3, 11-18, 21, 25...) | | | */
|
/* Class Flags (unused: 0, 1, 3, 11-18, 21, 25...) | | | */
|
||||||
/* =========== | | | */
|
/* =========== | | | */
|
||||||
/* | | | */
|
/* | | | */
|
||||||
|
|
|
@ -171,16 +171,14 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
|
||||||
|
|
||||||
char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
|
char *zend_visibility_string(uint32_t fn_flags) /* {{{ */
|
||||||
{
|
{
|
||||||
if (fn_flags & ZEND_ACC_PRIVATE) {
|
|
||||||
return "private";
|
|
||||||
}
|
|
||||||
if (fn_flags & ZEND_ACC_PROTECTED) {
|
|
||||||
return "protected";
|
|
||||||
}
|
|
||||||
if (fn_flags & ZEND_ACC_PUBLIC) {
|
if (fn_flags & ZEND_ACC_PUBLIC) {
|
||||||
return "public";
|
return "public";
|
||||||
|
} else if (fn_flags & ZEND_ACC_PRIVATE) {
|
||||||
|
return "private";
|
||||||
|
} else {
|
||||||
|
ZEND_ASSERT(fn_flags & ZEND_ACC_PROTECTED);
|
||||||
|
return "protected";
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -684,7 +682,7 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
|
||||||
|
|
||||||
if (UNEXPECTED(child)) {
|
if (UNEXPECTED(child)) {
|
||||||
child_info = Z_PTR_P(child);
|
child_info = Z_PTR_P(child);
|
||||||
if (UNEXPECTED(parent_info->flags & (ZEND_ACC_PRIVATE|ZEND_ACC_SHADOW))) {
|
if (UNEXPECTED(parent_info->flags & ZEND_ACC_PRIVATE)) {
|
||||||
child_info->flags |= ZEND_ACC_CHANGED;
|
child_info->flags |= ZEND_ACC_CHANGED;
|
||||||
} else {
|
} else {
|
||||||
if (UNEXPECTED((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC))) {
|
if (UNEXPECTED((parent_info->flags & ZEND_ACC_STATIC) != (child_info->flags & ZEND_ACC_STATIC))) {
|
||||||
|
@ -711,20 +709,10 @@ static void do_inherit_property(zend_property_info *parent_info, zend_string *ke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (UNEXPECTED(parent_info->flags & ZEND_ACC_PRIVATE)) {
|
if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
|
||||||
if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
|
child_info = zend_duplicate_property_info_internal(parent_info);
|
||||||
child_info = zend_duplicate_property_info_internal(parent_info);
|
|
||||||
} else {
|
|
||||||
child_info = zend_duplicate_property_info(parent_info);
|
|
||||||
}
|
|
||||||
child_info->flags &= ~ZEND_ACC_PRIVATE; /* it's not private anymore */
|
|
||||||
child_info->flags |= ZEND_ACC_SHADOW; /* but it's a shadow of private */
|
|
||||||
} else {
|
} else {
|
||||||
if (UNEXPECTED(ce->type & ZEND_INTERNAL_CLASS)) {
|
child_info = parent_info;
|
||||||
child_info = zend_duplicate_property_info_internal(parent_info);
|
|
||||||
} else {
|
|
||||||
child_info = parent_info;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_zend_hash_append_ptr(&ce->properties_info, key, child_info);
|
_zend_hash_append_ptr(&ce->properties_info, key, child_info);
|
||||||
}
|
}
|
||||||
|
@ -1681,11 +1669,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce, zend_class_ent
|
||||||
|
|
||||||
/* next: check for conflicts with current class */
|
/* next: check for conflicts with current class */
|
||||||
if ((coliding_prop = zend_hash_find_ptr(&ce->properties_info, prop_name)) != NULL) {
|
if ((coliding_prop = zend_hash_find_ptr(&ce->properties_info, prop_name)) != NULL) {
|
||||||
if (coliding_prop->flags & ZEND_ACC_SHADOW) {
|
if ((coliding_prop->flags & ZEND_ACC_PRIVATE) && coliding_prop->ce != ce) {
|
||||||
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);
|
zend_hash_del(&ce->properties_info, prop_name);
|
||||||
flags |= ZEND_ACC_CHANGED;
|
flags |= ZEND_ACC_CHANGED;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -326,13 +326,16 @@ static zend_always_inline int zend_verify_property_access(zend_property_info *pr
|
||||||
if (property_info->flags & ZEND_ACC_PUBLIC) {
|
if (property_info->flags & ZEND_ACC_PUBLIC) {
|
||||||
return 1;
|
return 1;
|
||||||
} else if (property_info->flags & ZEND_ACC_PRIVATE) {
|
} else if (property_info->flags & ZEND_ACC_PRIVATE) {
|
||||||
if (EG(fake_scope)) {
|
if (property_info->ce == ce) {
|
||||||
scope = EG(fake_scope);
|
if (EG(fake_scope)) {
|
||||||
} else {
|
scope = EG(fake_scope);
|
||||||
scope = zend_get_executed_scope();
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
|
return ce == scope;
|
||||||
}
|
}
|
||||||
return (ce == scope || property_info->ce == scope);
|
} else {
|
||||||
} else if (property_info->flags & ZEND_ACC_PROTECTED) {
|
ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
|
||||||
if (EG(fake_scope)) {
|
if (EG(fake_scope)) {
|
||||||
scope = EG(fake_scope);
|
scope = EG(fake_scope);
|
||||||
} else {
|
} else {
|
||||||
|
@ -377,39 +380,67 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c
|
||||||
if (EXPECTED(zv != NULL)) {
|
if (EXPECTED(zv != NULL)) {
|
||||||
property_info = (zend_property_info*)Z_PTR_P(zv);
|
property_info = (zend_property_info*)Z_PTR_P(zv);
|
||||||
flags = property_info->flags;
|
flags = property_info->flags;
|
||||||
if (UNEXPECTED((flags & ZEND_ACC_SHADOW) != 0)) {
|
|
||||||
/* if it's a shadow - go to access it's private */
|
if (flags & ZEND_ACC_PUBLIC) {
|
||||||
property_info = NULL;
|
check_changed:
|
||||||
} else {
|
if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))) {
|
||||||
if (EXPECTED(zend_verify_property_access(property_info, ce) != 0)) {
|
no_changed:
|
||||||
if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))
|
if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
|
||||||
|| UNEXPECTED((flags & ZEND_ACC_PRIVATE))) {
|
if (!silent) {
|
||||||
if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
|
zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
|
||||||
if (!silent) {
|
|
||||||
zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
|
|
||||||
}
|
|
||||||
return ZEND_DYNAMIC_PROPERTY_OFFSET;
|
|
||||||
}
|
}
|
||||||
goto exit;
|
return ZEND_DYNAMIC_PROPERTY_OFFSET;
|
||||||
}
|
}
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
goto check_scope;
|
||||||
|
} else if (flags & ZEND_ACC_PRIVATE) {
|
||||||
|
if (property_info->ce != ce) {
|
||||||
|
/* if it's a shadow - go to access it's private */
|
||||||
|
property_info = NULL;
|
||||||
|
goto check_scope;
|
||||||
|
} else {
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
|
if (ce == scope) {
|
||||||
|
goto no_changed;
|
||||||
|
} else {
|
||||||
|
/* Try to look in the scope instead */
|
||||||
|
property_info = ZEND_WRONG_PROPERTY_INFO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ZEND_ASSERT(flags & ZEND_ACC_PROTECTED);
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
|
if (zend_check_protected(property_info->ce, scope)) {
|
||||||
|
goto check_changed;
|
||||||
} else {
|
} else {
|
||||||
/* Try to look in the scope instead */
|
/* Try to look in the scope instead */
|
||||||
property_info = ZEND_WRONG_PROPERTY_INFO;
|
property_info = ZEND_WRONG_PROPERTY_INFO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (EG(fake_scope)) {
|
|
||||||
scope = EG(fake_scope);
|
|
||||||
} else {
|
} else {
|
||||||
scope = zend_get_executed_scope();
|
check_scope:
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope != ce
|
if (scope != ce
|
||||||
&& scope
|
&& scope
|
||||||
&& is_derived_class(ce, scope)
|
&& is_derived_class(ce, scope)
|
||||||
&& (zv = zend_hash_find(&scope->properties_info, member)) != NULL
|
&& (zv = zend_hash_find(&scope->properties_info, member)) != NULL
|
||||||
&& ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
|
&& ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE
|
||||||
|
&& ((zend_property_info*)Z_PTR_P(zv))->ce == scope) {
|
||||||
property_info = (zend_property_info*)Z_PTR_P(zv);
|
property_info = (zend_property_info*)Z_PTR_P(zv);
|
||||||
if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0)) {
|
if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0)) {
|
||||||
return ZEND_DYNAMIC_PROPERTY_OFFSET;
|
return ZEND_DYNAMIC_PROPERTY_OFFSET;
|
||||||
|
@ -457,38 +488,66 @@ ZEND_API zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_s
|
||||||
if (EXPECTED(zv != NULL)) {
|
if (EXPECTED(zv != NULL)) {
|
||||||
property_info = (zend_property_info*)Z_PTR_P(zv);
|
property_info = (zend_property_info*)Z_PTR_P(zv);
|
||||||
flags = property_info->flags;
|
flags = property_info->flags;
|
||||||
if (UNEXPECTED((flags & ZEND_ACC_SHADOW) != 0)) {
|
|
||||||
/* if it's a shadow - go to access it's private */
|
if (flags & ZEND_ACC_PUBLIC) {
|
||||||
property_info = NULL;
|
check_changed:
|
||||||
} else {
|
if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))) {
|
||||||
if (EXPECTED(zend_verify_property_access(property_info, ce) != 0)) {
|
no_changed:
|
||||||
if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED))
|
if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
|
||||||
|| UNEXPECTED((flags & ZEND_ACC_PRIVATE))) {
|
if (!silent) {
|
||||||
if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) {
|
zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
|
||||||
if (!silent) {
|
|
||||||
zend_error(E_NOTICE, "Accessing static property %s::$%s as non static", ZSTR_VAL(ce->name), ZSTR_VAL(member));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
goto exit;
|
|
||||||
}
|
}
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
goto check_scope;
|
||||||
|
} else if (flags & ZEND_ACC_PRIVATE) {
|
||||||
|
if (property_info->ce != ce) {
|
||||||
|
/* if it's a shadow - go to access it's private */
|
||||||
|
property_info = NULL;
|
||||||
|
goto check_scope;
|
||||||
|
} else {
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
|
if (ce == scope) {
|
||||||
|
goto no_changed;
|
||||||
|
} else {
|
||||||
|
/* Try to look in the scope instead */
|
||||||
|
property_info = ZEND_WRONG_PROPERTY_INFO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ZEND_ASSERT(flags & ZEND_ACC_PROTECTED);
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
|
if (zend_check_protected(property_info->ce, scope)) {
|
||||||
|
goto check_changed;
|
||||||
} else {
|
} else {
|
||||||
/* Try to look in the scope instead */
|
/* Try to look in the scope instead */
|
||||||
property_info = ZEND_WRONG_PROPERTY_INFO;
|
property_info = ZEND_WRONG_PROPERTY_INFO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (EG(fake_scope)) {
|
|
||||||
scope = EG(fake_scope);
|
|
||||||
} else {
|
} else {
|
||||||
scope = zend_get_executed_scope();
|
check_scope:
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scope != ce
|
if (scope != ce
|
||||||
&& scope
|
&& scope
|
||||||
&& is_derived_class(ce, scope)
|
&& is_derived_class(ce, scope)
|
||||||
&& (zv = zend_hash_find(&scope->properties_info, member)) != NULL
|
&& (zv = zend_hash_find(&scope->properties_info, member)) != NULL
|
||||||
&& ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
|
&& ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE
|
||||||
|
&& ((zend_property_info*)Z_PTR_P(zv))->ce == scope) {
|
||||||
property_info = (zend_property_info*)Z_PTR_P(zv);
|
property_info = (zend_property_info*)Z_PTR_P(zv);
|
||||||
} else if (UNEXPECTED(property_info == NULL)) {
|
} else if (UNEXPECTED(property_info == NULL)) {
|
||||||
exit_dynamic:
|
exit_dynamic:
|
||||||
|
@ -519,35 +578,57 @@ ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_inf
|
||||||
const char *prop_name;
|
const char *prop_name;
|
||||||
zend_string *member;
|
zend_string *member;
|
||||||
size_t prop_name_len;
|
size_t prop_name_len;
|
||||||
|
zend_class_entry *scope;
|
||||||
|
|
||||||
if (ZSTR_VAL(prop_info_name)[0] == 0) {
|
if (ZSTR_VAL(prop_info_name)[0] == 0) {
|
||||||
zend_unmangle_property_name_ex(prop_info_name, &class_name, &prop_name, &prop_name_len);
|
zend_unmangle_property_name_ex(prop_info_name, &class_name, &prop_name, &prop_name_len);
|
||||||
member = zend_string_init(prop_name, prop_name_len, 0);
|
member = zend_string_init(prop_name, prop_name_len, 0);
|
||||||
|
property_info = zend_get_property_info(zobj->ce, member, 1);
|
||||||
|
zend_string_release_ex(member, 0);
|
||||||
|
if (property_info == NULL) {
|
||||||
|
if (class_name[0] != '*') {
|
||||||
|
/* we we're looking for a private prop */
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
} else if (property_info == ZEND_WRONG_PROPERTY_INFO) {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
if (class_name[0] != '*') {
|
||||||
|
if (!(property_info->flags & ZEND_ACC_PRIVATE)) {
|
||||||
|
/* we we're looking for a private prop but found a non private one of the same name */
|
||||||
|
return FAILURE;
|
||||||
|
} else if (strcmp(ZSTR_VAL(prop_info_name)+1, ZSTR_VAL(property_info->name)+1)) {
|
||||||
|
/* we we're looking for a private prop but found a private one of the same name but another class */
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
|
if (property_info->ce == scope) {
|
||||||
|
return SUCCESS;
|
||||||
|
} else {
|
||||||
|
return FAILURE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ZEND_ASSERT(property_info->flags & ZEND_ACC_PROTECTED);
|
||||||
|
if (EG(fake_scope)) {
|
||||||
|
scope = EG(fake_scope);
|
||||||
|
} else {
|
||||||
|
scope = zend_get_executed_scope();
|
||||||
|
}
|
||||||
|
return zend_check_protected(property_info->ce, scope) ? SUCCESS : FAILURE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
member = zend_string_copy(prop_info_name);
|
property_info = zend_get_property_info(zobj->ce, prop_info_name, 1);
|
||||||
}
|
if (property_info == NULL || property_info == ZEND_WRONG_PROPERTY_INFO) {
|
||||||
property_info = zend_get_property_info(zobj->ce, member, 1);
|
|
||||||
zend_string_release_ex(member, 0);
|
|
||||||
if (property_info == NULL) {
|
|
||||||
/* undefined public property */
|
|
||||||
if (class_name && class_name[0] != '*') {
|
|
||||||
/* we we're looking for a private prop */
|
|
||||||
return FAILURE;
|
return FAILURE;
|
||||||
}
|
}
|
||||||
|
ZEND_ASSERT(property_info->flags & ZEND_ACC_PUBLIC);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
} else if (property_info == ZEND_WRONG_PROPERTY_INFO) {
|
|
||||||
return FAILURE;
|
|
||||||
}
|
}
|
||||||
if (class_name && class_name[0] != '*') {
|
|
||||||
if (!(property_info->flags & ZEND_ACC_PRIVATE)) {
|
|
||||||
/* we we're looking for a private prop but found a non private one of the same name */
|
|
||||||
return FAILURE;
|
|
||||||
} else if (strcmp(ZSTR_VAL(prop_info_name)+1, ZSTR_VAL(property_info->name)+1)) {
|
|
||||||
/* we we're looking for a private prop but found a private one of the same name but another class */
|
|
||||||
return FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return zend_verify_property_access(property_info, zobj->ce) ? SUCCESS : FAILURE;
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
@ -1474,7 +1555,8 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
|
||||||
constructor = NULL;
|
constructor = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if ((constructor->common.fn_flags & ZEND_ACC_PROTECTED)) {
|
} else {
|
||||||
|
ZEND_ASSERT(constructor->common.fn_flags & ZEND_ACC_PROTECTED);
|
||||||
/* Ensure that if we're calling a protected function, we're allowed to do so.
|
/* Ensure that if we're calling a protected function, we're allowed to do so.
|
||||||
* Constructors only have prototype if they are defined by an interface but
|
* Constructors only have prototype if they are defined by an interface but
|
||||||
* it is the compilers responsibility to take care of the prototype.
|
* it is the compilers responsibility to take care of the prototype.
|
||||||
|
|
|
@ -242,7 +242,7 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||||
efree(ce->default_static_members_table);
|
efree(ce->default_static_members_table);
|
||||||
}
|
}
|
||||||
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
|
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
|
||||||
if (prop_info->ce == ce || (prop_info->flags & ZEND_ACC_SHADOW)) {
|
if (prop_info->ce == ce) {
|
||||||
zend_string_release_ex(prop_info->name, 0);
|
zend_string_release_ex(prop_info->name, 0);
|
||||||
if (prop_info->doc_comment) {
|
if (prop_info->doc_comment) {
|
||||||
zend_string_release_ex(prop_info->doc_comment, 0);
|
zend_string_release_ex(prop_info->doc_comment, 0);
|
||||||
|
|
|
@ -366,7 +366,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
|
||||||
zend_property_info *prop;
|
zend_property_info *prop;
|
||||||
|
|
||||||
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
|
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
|
||||||
if(prop->flags & ZEND_ACC_SHADOW) {
|
if ((prop->flags & ZEND_ACC_PRIVATE) && prop->ce != ce) {
|
||||||
count_shadow_props++;
|
count_shadow_props++;
|
||||||
} else if (prop->flags & ZEND_ACC_STATIC) {
|
} else if (prop->flags & ZEND_ACC_STATIC) {
|
||||||
count_static_props++;
|
count_static_props++;
|
||||||
|
@ -380,7 +380,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
|
||||||
zend_property_info *prop;
|
zend_property_info *prop;
|
||||||
|
|
||||||
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
|
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
|
||||||
if ((prop->flags & ZEND_ACC_STATIC) && !(prop->flags & ZEND_ACC_SHADOW)) {
|
if ((prop->flags & ZEND_ACC_STATIC) && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) {
|
||||||
_property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
|
_property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
|
||||||
}
|
}
|
||||||
} ZEND_HASH_FOREACH_END();
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
@ -427,7 +427,8 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
|
||||||
zend_property_info *prop;
|
zend_property_info *prop;
|
||||||
|
|
||||||
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
|
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
|
||||||
if (!(prop->flags & (ZEND_ACC_STATIC|ZEND_ACC_SHADOW))) {
|
if (!(prop->flags & ZEND_ACC_STATIC)
|
||||||
|
&& (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) {
|
||||||
_property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
|
_property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
|
||||||
}
|
}
|
||||||
} ZEND_HASH_FOREACH_END();
|
} ZEND_HASH_FOREACH_END();
|
||||||
|
@ -1242,7 +1243,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name,
|
||||||
tmp_ce = tmp_ce->parent;
|
tmp_ce = tmp_ce->parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmp_info && !(tmp_info->flags & ZEND_ACC_SHADOW)) { /* found something and it's not a parent's private */
|
if (tmp_info && (!(tmp_info->flags & ZEND_ACC_PRIVATE) || tmp_info->ce == tmp_ce)) { /* found something and it's not a parent's private */
|
||||||
prop = tmp_info;
|
prop = tmp_info;
|
||||||
} else { /* not found, use initial value */
|
} else { /* not found, use initial value */
|
||||||
ce = store_ce;
|
ce = store_ce;
|
||||||
|
@ -3764,9 +3765,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
|
||||||
zend_string *key;
|
zend_string *key;
|
||||||
|
|
||||||
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
|
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
|
||||||
if (((prop_info->flags & ZEND_ACC_SHADOW) &&
|
if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
|
||||||
prop_info->ce != ce) ||
|
|
||||||
((prop_info->flags & ZEND_ACC_PROTECTED) &&
|
|
||||||
!zend_check_protected(prop_info->ce, ce)) ||
|
!zend_check_protected(prop_info->ce, ce)) ||
|
||||||
((prop_info->flags & ZEND_ACC_PRIVATE) &&
|
((prop_info->flags & ZEND_ACC_PRIVATE) &&
|
||||||
prop_info->ce != ce)) {
|
prop_info->ce != ce)) {
|
||||||
|
@ -4220,7 +4219,7 @@ ZEND_METHOD(reflection_class, hasProperty)
|
||||||
|
|
||||||
GET_REFLECTION_OBJECT_PTR(ce);
|
GET_REFLECTION_OBJECT_PTR(ce);
|
||||||
if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
|
if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
|
||||||
if (property_info->flags & ZEND_ACC_SHADOW) {
|
if ((property_info->flags & ZEND_ACC_PRIVATE) && property_info->ce != ce) {
|
||||||
RETURN_FALSE;
|
RETURN_FALSE;
|
||||||
}
|
}
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
|
@ -4255,7 +4254,7 @@ ZEND_METHOD(reflection_class, getProperty)
|
||||||
|
|
||||||
GET_REFLECTION_OBJECT_PTR(ce);
|
GET_REFLECTION_OBJECT_PTR(ce);
|
||||||
if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
|
if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
|
||||||
if ((property_info->flags & ZEND_ACC_SHADOW) == 0) {
|
if (!(property_info->flags & ZEND_ACC_PRIVATE) || property_info->ce == ce) {
|
||||||
reflection_property_factory(ce, name, property_info, return_value);
|
reflection_property_factory(ce, name, property_info, return_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4297,7 +4296,10 @@ ZEND_METHOD(reflection_class, getProperty)
|
||||||
}
|
}
|
||||||
ce = ce2;
|
ce = ce2;
|
||||||
|
|
||||||
if ((property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len)) != NULL && (property_info->flags & ZEND_ACC_SHADOW) == 0) {
|
property_info = zend_hash_str_find_ptr(&ce->properties_info, str_name, str_name_len);
|
||||||
|
if (property_info != NULL
|
||||||
|
&& (!(property_info->flags & ZEND_ACC_PRIVATE)
|
||||||
|
|| property_info->ce == ce)) {
|
||||||
reflection_property_factory_str(ce, str_name, str_name_len, property_info, return_value);
|
reflection_property_factory_str(ce, str_name, str_name_len, property_info, return_value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -4316,7 +4318,7 @@ static int _addproperty(zval *el, int num_args, va_list args, zend_hash_key *has
|
||||||
zval *retval = va_arg(args, zval*);
|
zval *retval = va_arg(args, zval*);
|
||||||
long filter = va_arg(args, long);
|
long filter = va_arg(args, long);
|
||||||
|
|
||||||
if (pptr->flags & ZEND_ACC_SHADOW) {
|
if ((pptr->flags & ZEND_ACC_PRIVATE) && pptr->ce != ce) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5278,7 +5280,10 @@ ZEND_METHOD(reflection_property, __construct)
|
||||||
/* returns out of this function */
|
/* returns out of this function */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) == NULL || (property_info->flags & ZEND_ACC_SHADOW)) {
|
property_info = zend_hash_find_ptr(&ce->properties_info, name);
|
||||||
|
if (property_info == NULL
|
||||||
|
|| ((property_info->flags & ZEND_ACC_PRIVATE)
|
||||||
|
&& property_info->ce != ce)) {
|
||||||
/* Check for dynamic properties */
|
/* Check for dynamic properties */
|
||||||
if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
|
if (property_info == NULL && Z_TYPE_P(classname) == IS_OBJECT && Z_OBJ_HT_P(classname)->get_properties) {
|
||||||
if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname), name)) {
|
if (zend_hash_exists(Z_OBJ_HT_P(classname)->get_properties(classname), name)) {
|
||||||
|
@ -5530,7 +5535,7 @@ ZEND_METHOD(reflection_property, getDeclaringClass)
|
||||||
|
|
||||||
ce = tmp_ce = ref->ce;
|
ce = tmp_ce = ref->ce;
|
||||||
while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, ref->unmangled_name)) != NULL) {
|
while (tmp_ce && (tmp_info = zend_hash_find_ptr(&tmp_ce->properties_info, ref->unmangled_name)) != NULL) {
|
||||||
if (tmp_info->flags & ZEND_ACC_PRIVATE || tmp_info->flags & ZEND_ACC_SHADOW) {
|
if (tmp_info->flags & ZEND_ACC_PRIVATE) {
|
||||||
/* it's a private property, so it can't be inherited */
|
/* it's a private property, so it can't be inherited */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue