git.iko.soy/typeable/pandoc
on master help sign in
Markdown reader: Fixed link parser to avoid exponential slowdowns.

Previously the parser would hang on input like this: [[[[[[[[[[[[[[[[[[hi We fixed this by making the link parser parser characters between balanced brackets (skipping brackets in inline code spans), then parsing the result as an inline list. One change is that [hi *there]* bud](/url) is now no longer parsed as a link. But in this respect pandoc behaved differently from most other implementations anyway, so that seems okay. All current tests pass. Added test for this case. Closes #620.

commit22bd34fa338edc5fb38cce5adfa11ffbc451b0d4 authorJohn MacFarlane <jgm@berkeley.edu> dateSat 22 Sep 2012, 13:59 (14 years ago) parent1038606
2 files changed+14−8
src/Text/Pandoc/Readers/Markdown.hs+12−8 tests/Tests/Readers/Markdown.hs+2
src/Text/Pandoc/Readers/Markdown.hs+12−8
@@ -132,15 +132,19 @@ litChar = escapedChar'
132132-- | Parse a sequence of inline elements between square brackets,
133133-- including inlines between balanced pairs of square brackets.
134134inlinesInBalancedBrackets :: Parser [Char] ParserState (F Inlines)
135−inlinesInBalancedBrackets = try $ do
135+inlinesInBalancedBrackets = charsInBalancedBrackets >>=
136+ parseFromString (trimInlinesF . mconcat <$> many inline)
137+
138+charsInBalancedBrackets :: Parser [Char] ParserState [Char]
139+charsInBalancedBrackets = do
136140 char '['
137− result <- manyTill ( (do lookAhead $ try $ do x <- inline
138− guard (runF x def == B.str "[")
139− bal <- inlinesInBalancedBrackets
140− return $ (\x -> B.str "[" <> x <> B.str "]") <$> bal)
141− <|> inline)
142− (char ']')
143− return $ mconcat result
141+ result <- manyTill ( many1 (noneOf "`[]\n")
142+ <|> (snd <$> withRaw code)
143+ <|> ((\xs -> '[' : xs ++ "]") <$> charsInBalancedBrackets)
144+ <|> count 1 (satisfy (/='\n'))
145+ <|> (newline >> notFollowedBy blankline >> return "\n")
146+ ) (char ']')
147+ return $ concat result
144148
145149--
146150-- document structure
tests/Tests/Readers/Markdown.hs+2
@@ -48,6 +48,8 @@ tests = [ testGroup "inline code"
4848 [ "in URL" =:
4949 "\\begin\n" =?> para (text "\\begin")
5050 ]
51+ , "unbalanced brackets" =:
52+ "[[[[[[[[[[[[[[[hi" =?> para (text "[[[[[[[[[[[[[[[hi")
5153 , testGroup "backslash escapes"
5254 [ "in URL" =:
5355 "[hi](/there\\))"