Skip to content

Commit 7d13444

Browse files
committed
handle protected/private lookups in outer classes
1 parent 369af23 commit 7d13444

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);
@@ -1861,6 +1866,8 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
18611866
/* Check access level */
18621867
if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
18631868
scope = zend_get_executed_scope();
1869+
zend_class_entry *original_scope = scope;
1870+
check_lexical_scope:
18641871

18651872
if (fbc->common.scope != scope) {
18661873
if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
@@ -1878,7 +1885,11 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
18781885
if (zobj->ce->__call) {
18791886
fbc = zend_get_user_call_function(zobj->ce, method_name);
18801887
} else {
1881-
zend_bad_method_call(fbc, method_name, scope);
1888+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
1889+
scope = scope->lexical_scope;
1890+
goto check_lexical_scope;
1891+
}
1892+
zend_bad_method_call(fbc, method_name, original_scope);
18821893
fbc = NULL;
18831894
}
18841895
}
@@ -1937,12 +1948,20 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
19371948
fbc = Z_FUNC_P(func);
19381949
if (!(fbc->op_array.fn_flags & ZEND_ACC_PUBLIC)) {
19391950
zend_class_entry *scope = zend_get_executed_scope();
1951+
zend_class_entry *original_scope = scope;
1952+
1953+
check_lexical_scope:
19401954
if (UNEXPECTED(fbc->common.scope != scope)) {
19411955
if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
19421956
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
19431957
zend_function *fallback_fbc = get_static_method_fallback(ce, function_name);
19441958
if (!fallback_fbc) {
1945-
zend_bad_method_call(fbc, function_name, scope);
1959+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
1960+
scope = scope->lexical_scope;
1961+
goto check_lexical_scope;
1962+
}
1963+
1964+
zend_bad_method_call(fbc, function_name, original_scope);
19461965
}
19471966
fbc = fallback_fbc;
19481967
}
@@ -2019,10 +2038,15 @@ ZEND_API zval *zend_std_get_static_property_with_info(zend_class_entry *ce, zend
20192038

20202039
if (!(property_info->flags & ZEND_ACC_PUBLIC)) {
20212040
zend_class_entry *scope = get_fake_or_executed_scope();
2041+
check_lexical_scope:
20222042
if (property_info->ce != scope) {
20232043
if (UNEXPECTED(property_info->flags & ZEND_ACC_PRIVATE)
20242044
|| UNEXPECTED(!is_protected_compatible_scope(property_info->ce, scope))) {
20252045
if (type != BP_VAR_IS) {
2046+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
2047+
scope = scope->lexical_scope;
2048+
goto check_lexical_scope;
2049+
}
20262050
zend_bad_property_access(property_info, ce, property_name);
20272051
}
20282052
return NULL;
@@ -2103,10 +2127,16 @@ ZEND_API zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
21032127
if (constructor) {
21042128
if (UNEXPECTED(!(constructor->op_array.fn_flags & ZEND_ACC_PUBLIC))) {
21052129
zend_class_entry *scope = get_fake_or_executed_scope();
2130+
zend_class_entry *original_scope = scope;
2131+
check_lexical_scope:
21062132
if (UNEXPECTED(constructor->common.scope != scope)) {
21072133
if (UNEXPECTED(constructor->op_array.fn_flags & ZEND_ACC_PRIVATE)
21082134
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
2109-
zend_bad_constructor_call(constructor, scope);
2135+
if (scope && scope->lexical_scope && scope->lexical_scope->type != ZEND_NAMESPACE_CLASS) {
2136+
scope = scope->lexical_scope;
2137+
goto check_lexical_scope;
2138+
}
2139+
zend_bad_constructor_call(constructor, original_scope);
21102140
zend_object_store_ctor_failed(zobj);
21112141
constructor = NULL;
21122142
}

0 commit comments

Comments
 (0)