Skip to content

Commit e0dab39

Browse files
committed
handle visibility of methods
1 parent f9a7f66 commit e0dab39

File tree

4 files changed

+93
-0
lines changed

4 files changed

+93
-0
lines changed

Zend/zend_object_handlers.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
18191819
/* Check access level */
18201820
if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
18211821
scope = zend_get_executed_scope();
1822+
check_lexical_scope:
18221823

18231824
if (fbc->common.scope != scope) {
18241825
if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
@@ -1836,6 +1837,10 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
18361837
if (zobj->ce->__call) {
18371838
fbc = zend_get_user_call_function(zobj->ce, method_name);
18381839
} else {
1840+
if (scope->lexical_scope) {
1841+
scope = scope->lexical_scope;
1842+
goto check_lexical_scope;
1843+
}
18391844
zend_bad_method_call(fbc, method_name, scope);
18401845
fbc = NULL;
18411846
}
@@ -1895,11 +1900,17 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
18951900
fbc = Z_FUNC_P(func);
18961901
if (!(fbc->op_array.fn_flags & ZEND_ACC_PUBLIC)) {
18971902
zend_class_entry *scope = zend_get_executed_scope();
1903+
check_lexical_scope:
18981904
if (UNEXPECTED(fbc->common.scope != scope)) {
18991905
if (UNEXPECTED(fbc->op_array.fn_flags & ZEND_ACC_PRIVATE)
19001906
|| UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
19011907
zend_function *fallback_fbc = get_static_method_fallback(ce, function_name);
19021908
if (!fallback_fbc) {
1909+
if (scope->lexical_scope) {
1910+
scope = scope->lexical_scope;
1911+
goto check_lexical_scope;
1912+
}
1913+
19031914
zend_bad_method_call(fbc, function_name, scope);
19041915
}
19051916
fbc = fallback_fbc;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
accessing outer private methods
3+
--FILE--
4+
<?php
5+
6+
class Outer {
7+
private function test() {
8+
echo __METHOD__ . "\n";
9+
}
10+
class Middle {
11+
private static function test() {
12+
echo __METHOD__ . "\n";
13+
}
14+
class Inner {
15+
public function test() {
16+
Outer:>Middle::test();
17+
$t = new Outer();
18+
$t->test();
19+
}
20+
}
21+
}
22+
}
23+
new Outer:>Middle:>Inner()->test();
24+
?>
25+
--EXPECT--
26+
Outer:>Middle::test
27+
Outer::test
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
--TEST--
2+
scope doesn't bypass scope
3+
--FILE--
4+
<?php
5+
6+
class Outer {
7+
private function test() {
8+
echo __METHOD__ . "\n";
9+
}
10+
class Middle {
11+
private static function test() {
12+
echo __METHOD__ . "\n";
13+
}
14+
class Inner {
15+
public function testit() {
16+
$this->test();
17+
}
18+
}
19+
}
20+
}
21+
new Outer:>Middle:>Inner()->testit();
22+
?>
23+
--EXPECTF--
24+
Fatal error: Uncaught Error: Call to undefined method Outer:>Middle:>Inner::test() in %s:%d
25+
Stack trace:
26+
#0 %s(%d): Outer:>Middle:>Inner->testit()
27+
#1 {main}
28+
thrown in %s on line %d
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
accessing outer protected methods
3+
--FILE--
4+
<?php
5+
6+
class Outer {
7+
protected function test() {
8+
echo __METHOD__ . "\n";
9+
}
10+
class Middle {
11+
protected static function test() {
12+
echo __METHOD__ . "\n";
13+
}
14+
class Inner {
15+
public function test() {
16+
Outer:>Middle::test();
17+
$t = new Outer();
18+
$t->test();
19+
}
20+
}
21+
}
22+
}
23+
new Outer:>Middle:>Inner()->test();
24+
?>
25+
--EXPECT--
26+
Outer:>Middle::test
27+
Outer::test

0 commit comments

Comments
 (0)