Skip to content

Commit

Permalink
Merge pull request #41 from thephpleague/fix-infinite-loop
Browse files Browse the repository at this point in the history
Fix infinite loop and link-in-link-in-image parsing (#37)
  • Loading branch information
colinodell committed Dec 27, 2014
2 parents ec8bcb9 + b02cf79 commit da01b49
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 8 deletions.
24 changes: 24 additions & 0 deletions src/Delimiter/Delimiter.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class Delimiter
/** @var bool */
protected $canClose;

/** @var bool */
protected $active;

/** @var int|null */
protected $index;

Expand All @@ -55,6 +58,7 @@ public function __construct($char, $numDelims, $pos, $canOpen, $canClose, $index
$this->pos = $pos;
$this->canOpen = $canOpen;
$this->canClose = $canClose;
$this->active = true;
$this->index = $index;
}

Expand Down Expand Up @@ -98,6 +102,26 @@ public function setCanOpen($canOpen)
return $this;
}

/**
* @return bool
*/
public function isActive()
{
return $this->active;
}

/**
* @param bool $active
*
* @return $this
*/
public function setActive($active)
{
$this->active = $active;

return $this;
}

/**
* @return String
*/
Expand Down
10 changes: 2 additions & 8 deletions src/Delimiter/DelimiterStack.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,11 @@ public function removeAll(Delimiter $stackBottom = null)
public function removeEarlierMatches($character)
{
$opener = $this->top;
$closerAbove = null;
while ($opener !== null) {
if ($opener->getChar() === $character) {
if ($closerAbove) {
$closerAbove->setPrevious($opener->getPrevious());
} else {
$this->top = $opener->getPrevious();
}
} else {
$closerAbove = $opener;
$opener->setActive(false);
}

$opener = $opener->getPrevious();
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/Inline/Parser/CloseBracketParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ public function parse(ContextInterface $context, InlineParserContext $inlineCont
return false;
}

if (!$opener->isActive()) {
// no matched opener; remove from emphasis stack
$inlineContext->getDelimiterStack()->removeDelimiter($opener);

return false;
}

$isImage = $opener->getChar() === '!';

// Instead of copying a slice, we null out the parts of inlines that don't correspond to linkText; later, we'll
Expand Down

0 comments on commit da01b49

Please sign in to comment.