Skip to content

Commit

Permalink
Optimize repeated parsing of links without closing brace
Browse files Browse the repository at this point in the history
  • Loading branch information
colinodell committed Dec 7, 2024
1 parent 540d850 commit 5ce491f
Showing 1 changed file with 33 additions and 8 deletions.
41 changes: 33 additions & 8 deletions src/Util/LinkParserHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,7 @@ final class LinkParserHelper
public static function parseLinkDestination(Cursor $cursor): ?string
{
if ($cursor->getCurrentCharacter() === '<') {
if ($res = $cursor->match(RegexHelper::REGEX_LINK_DESTINATION_BRACES)) {
// Chop off surrounding <..>:
return UrlEncoder::unescapeAndEncode(
RegexHelper::unescape(\substr($res, 1, -1))
);
}

return null;
return self::parseDestinationBraces($cursor);
}

$destination = self::manuallyParseLinkDestination($cursor);
Expand Down Expand Up @@ -137,4 +130,36 @@ private static function manuallyParseLinkDestination(Cursor $cursor): ?string

return $destination;
}

/** @var \WeakReference<Cursor>|null */
private static ?\WeakReference $lastCursor = null;
private static bool $lastCursorLacksClosingBrace = false;

private static function parseDestinationBraces(Cursor $cursor): ?string
{
// Optimization: If we've previously parsed this cursor and returned `null`, we know
// that no closing brace exists, so we can skip the regex entirely. This helps avoid
// certain pathological cases where the regex engine can take a very long time to
// determine that no match exists.
if (self::$lastCursor !== null && self::$lastCursor->get() === $cursor) {
if (self::$lastCursorLacksClosingBrace) {
return null;
}
} else {
self::$lastCursor = \WeakReference::create($cursor);
}

if ($res = $cursor->match(RegexHelper::REGEX_LINK_DESTINATION_BRACES)) {
self::$lastCursorLacksClosingBrace = false;

// Chop off surrounding <..>:
return UrlEncoder::unescapeAndEncode(
RegexHelper::unescape(\substr($res, 1, -1))
);
}

self::$lastCursorLacksClosingBrace = true;

return null;
}
}

0 comments on commit 5ce491f

Please sign in to comment.