php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81369 Private and protected methods are called as public!
Submitted: 2021-08-17 12:07 UTC Modified: 2021-08-17 13:03 UTC
From: mail at zabmix dot ru Assigned:
Status: Not a bug Package: Scripting Engine problem
PHP Version: 7.3.29 OS: Any
Private report: No CVE-ID: None
 [2021-08-17 12:07 UTC] mail at zabmix dot ru
Description:
------------
Any method properties are ignored when called inside a __call function.

Test script:
---------------
class One {
	protected function cat() { return 'this is cat'; }
}

class Two extends One {
	private function dog() { return 'this is dog'; }
	public function __call($name, array $args = []) {
		return call_user_func_array([new Three, $name], $args) . PHP_EOL;
	}
}

class Three extends Two {
	public function bird() { return 'this is bird'; }
}

$my = new Two();
echo $my->cat();
echo $my->dog();
echo $my->bird();

Expected result:
----------------
I expect at least a scoping error


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-08-17 12:12 UTC] mail at zabmix dot ru
-Summary: No version features php +Summary: Private and protected methods are called as public! -Operating System: Any (Windows 10 and Ubuntu test) +Operating System: Any
 [2021-08-17 12:12 UTC] mail at zabmix dot ru
If you call a non-existent method, the script will start to occupy all memory

echo $my->test();
 [2021-08-17 12:35 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2021-08-17 12:35 UTC] nikic@php.net
__call() is invoked for inaccessible methods. The methods you call are accessible from the __call() scope, so they succeed.
 [2021-08-17 12:35 UTC] nikic@php.net
-Type: Security +Type: Bug
 [2021-08-17 12:45 UTC] mail at zabmix dot ru
How can I get around this and only use methods that are public? Use ReflectionMethod for validation?
 [2021-08-17 13:03 UTC] nikic@php.net
Yes, using reflection should work. Or you can use closure rebinding to simulate a call as if it happened from a different scope (e.g. global scope).
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 23 12:01:31 2024 UTC