diff --git a/src/pocketmine/plugin/PluginManager.php b/src/pocketmine/plugin/PluginManager.php index 7e1a8ad3d..56c2ad1fd 100644 --- a/src/pocketmine/plugin/PluginManager.php +++ b/src/pocketmine/plugin/PluginManager.php @@ -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; } /**