PluginManager: added event call recursion limit, closes #2109

This prevents unexplained segfaults on accidental event call recursion by limiting the max depth of event call stack to 50. If another event attempts to be called, an exception will be thrown.
This commit is contained in:
Dylan K. Taylor 2018-03-21 10:40:08 +00:00
parent 49fbbea7bf
commit d2fb32c28a

View File

@ -40,6 +40,7 @@ use pocketmine\timings\TimingsHandler;
* Manages all the plugins, Permissions and Permissibles
*/
class PluginManager{
private const MAX_EVENT_CALL_DEPTH = 50;
/** @var Server */
private $server;
@ -87,6 +88,9 @@ class PluginManager{
*/
protected $fileAssociations = [];
/** @var int */
private $eventCallDepth = 0;
/** @var TimingsHandler */
public static $pluginParentTimer;
@ -671,9 +675,15 @@ class PluginManager{
* @param Event $event
*/
public function callEvent(Event $event){
if($this->eventCallDepth >= self::MAX_EVENT_CALL_DEPTH){
//this exception will be caught by the parent event call if all else fails
throw new \RuntimeException("Recursive event call detected (reached max depth of " . self::MAX_EVENT_CALL_DEPTH . " calls)");
}
$handlerList = HandlerList::getHandlerListFor(get_class($event));
assert($handlerList !== null, "Called event should have a valid HandlerList");
++$this->eventCallDepth;
foreach(EventPriority::ALL as $priority){
$currentList = $handlerList;
while($currentList !== null){
@ -699,6 +709,7 @@ class PluginManager{
$currentList = $currentList->getParent();
}
}
--$this->eventCallDepth;
}
/**