Skip to content

Commit 9f5f2a4

Browse files
committed
handle protected/private lookups in outer classes
1 parent 9302221 commit 9f5f2a4

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

Zend/zend_object_handlers.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c
381381
if (flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
382382
zend_class_entry *scope = get_fake_or_executed_scope();
383383

384+
check_lexical_scope:
384385
if (property_info->ce != scope) {
385386
if (flags & ZEND_ACC_CHANGED) {
386387
zend_property_info *p = zend_get_parent_private_property(scope, ce, member);
@@ -402,6 +403,10 @@ static zend_always_inline uintptr_t zend_get_property_offset(zend_class_entry *c
402403
goto dynamic;
403404
} else {
404405
wrong:
406+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
407+
scope = scope->lexical_scope;
408+
goto check_lexical_scope;
409+
}
405410
/* Information was available, but we were denied access. Error out. */
406411
if (!silent) {
407412
zend_bad_property_access(property_info, ce, member);
@@ -1818,6 +1823,8 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
18181823
/* Check access level */
18191824
if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
18201825
scope = zend_get_executed_scope();
1826+
zend_class_entry *original_scope = scope;
1827+
check_lexical_scope:
18211828

18221829
if (fbc->common.scope != scope) {
18231830
if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
@@ -1835,7 +1842,11 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
18351842
if (zobj->ce->__call) {
18361843
fbc = zend_get_user_call_function(zobj->ce, method_name);
18371844
} else {
1838-
zend_bad_method_call(fbc, method_name, scope);
1845+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
1846+
scope = scope->lexical_scope;
1847+
goto check_lexical_scope;
1848+
}
1849+
zend_bad_method_call(fbc, method_name, original_scope);
18391850
fbc = NULL;
18401851
}
18411852
}
@@ -1894,12 +1905,20 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
18941905
fbc = Z_FUNC_P(func);
18951906
if (!(fbc->op_array.fn_flags & ZEND_ACC_PUBLIC)) {
18961907
zend_class_entry *scope = zend_get_executed_scope();
1908+
zend_class_entry *original_scope = scope;
1909+
1910+
check_lexical_scope:
18971911
if (UNEXPECTED(fbc->common.scope != scope)) {
18981912
if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
18991913
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
19001914
zend_function *fallback_fbc = get_static_method_fallback(ce, function_name);
19011915
if (!fallback_fbc) {
1902-
zend_bad_method_call(fbc, function_name, scope);
1916+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
1917+
scope = scope->lexical_scope;
1918+
goto check_lexical_scope;
1919+
}
1920+
1921+
zend_bad_method_call(fbc, function_name, original_scope);
19031922
}
19041923
fbc = fallback_fbc;
19051924
}
@@ -1976,10 +1995,15 @@ ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend
19761995

19771996
if (!(property_info->flags & ZEND_ACC_PUBLIC)) {
19781997
zend_class_entry *scope = get_fake_or_executed_scope();
1998+
check_lexical_scope:
19791999
if (property_info->ce != scope) {
19802000
if (UNEXPECTED(property_info->flags & ZEND_ACC_PRIVATE)
19812001
|| UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) {
19822002
if (type != BP_VAR_IS) {
2003+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
2004+
scope = scope->lexical_scope;
2005+
goto check_lexical_scope;
2006+
}
19832007
zend_bad_property_access(property_info, ce, property_name);
19842008
}
19852009
return NULL;
@@ -2060,10 +2084,16 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
20602084
if (constructor) {
20612085
if (UNEXPECTED(!(constructor->op_array.fn_flags & ZEND_ACC_PUBLIC))) {
20622086
zend_class_entry *scope = get_fake_or_executed_scope();
2087+
zend_class_entry *original_scope = scope;
2088+
check_lexical_scope:
20632089
if (UNEXPECTED(constructor->common.scope != scope)) {
20642090
if (UNEXPECTED(constructor->op_array.fn_flags & ZEND_ACC_PRIVATE)
20652091
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
2066-
zend_bad_constructor_call(constructor, scope);
2092+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
2093+
scope = scope->lexical_scope;
2094+
goto check_lexical_scope;
2095+
}
2096+
zend_bad_constructor_call(constructor, original_scope);
20672097
zend_object_store_ctor_failed(zobj);
20682098
constructor = NULL;
20692099
}

0 commit comments

Comments
 (0)