mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Limit recursion depth by configurable
Fixes https://github.com/erusev/parsedown/issues/681
This commit is contained in:
51
src/Configurables/RecursionLimiter.php
Normal file
51
src/Configurables/RecursionLimiter.php
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace Erusev\Parsedown\Configurables;
|
||||
|
||||
use Erusev\Parsedown\Configurable;
|
||||
|
||||
final class RecursionLimiter implements Configurable
|
||||
{
|
||||
/** @var int */
|
||||
private $maxDepth;
|
||||
|
||||
/** @var int */
|
||||
private $currentDepth;
|
||||
|
||||
/**
|
||||
* @param int $maxDepth
|
||||
* @param int $currentDepth
|
||||
*/
|
||||
private function __construct($maxDepth, $currentDepth)
|
||||
{
|
||||
$this->maxDepth = $maxDepth;
|
||||
$this->currentDepth = $currentDepth;
|
||||
}
|
||||
|
||||
/** @return self */
|
||||
public static function initial()
|
||||
{
|
||||
return self::maxDepth(256);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $maxDepth
|
||||
* @return self
|
||||
*/
|
||||
public static function maxDepth($maxDepth)
|
||||
{
|
||||
return new self($maxDepth, 0);
|
||||
}
|
||||
|
||||
/** @return self */
|
||||
public function increment()
|
||||
{
|
||||
return new self($this->maxDepth, $this->currentDepth + 1);
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function isDepthExceeded()
|
||||
{
|
||||
return ($this->maxDepth < $this->currentDepth);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ use Erusev\Parsedown\Components\Inlines\PlainText;
|
||||
use Erusev\Parsedown\Components\StateUpdatingBlock;
|
||||
use Erusev\Parsedown\Configurables\BlockTypes;
|
||||
use Erusev\Parsedown\Configurables\InlineTypes;
|
||||
use Erusev\Parsedown\Configurables\RecursionLimiter;
|
||||
use Erusev\Parsedown\Html\Renderable;
|
||||
use Erusev\Parsedown\Html\Renderables\Text;
|
||||
use Erusev\Parsedown\Parsing\Excerpt;
|
||||
@@ -82,6 +83,14 @@ final class Parsedown
|
||||
*/
|
||||
public static function blocks(Lines $Lines, State $State)
|
||||
{
|
||||
$RecursionLimiter = $State->get(RecursionLimiter::class)->increment();
|
||||
|
||||
if ($RecursionLimiter->isDepthExceeded()) {
|
||||
$State = $State->setting(new BlockTypes([], []));
|
||||
}
|
||||
|
||||
$State = $State->setting($RecursionLimiter);
|
||||
|
||||
/** @var Block[] */
|
||||
$Blocks = [];
|
||||
/** @var Block|null */
|
||||
@@ -180,6 +189,14 @@ final class Parsedown
|
||||
# standardize line breaks
|
||||
$text = \str_replace(["\r\n", "\r"], "\n", $text);
|
||||
|
||||
$RecursionLimiter = $State->get(RecursionLimiter::class)->increment();
|
||||
|
||||
if ($RecursionLimiter->isDepthExceeded()) {
|
||||
return [Plaintext::build(new Excerpt($text, 0), $State)];
|
||||
}
|
||||
|
||||
$State = $State->setting($RecursionLimiter);
|
||||
|
||||
/** @var Inline[] */
|
||||
$Inlines = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user