git.iko.soy/typeable/pandoc
on master help sign in
Limit nesting of strong/emph.
7a602d2John MacFarlane
src/Text/Pandoc/Parsing.hs+2
@@ -629,6 +629,7 @@ data ParserState = ParserState
629 { stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
629 { stateParseRaw :: Bool, -- ^ Parse raw HTML and LaTeX?
630 stateParserContext :: ParserContext, -- ^ Inside list?
630 stateParserContext :: ParserContext, -- ^ Inside list?
631 stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
631 stateQuoteContext :: QuoteContext, -- ^ Inside quoted environment?
632+ stateMaxNestingLevel :: Int, -- ^ Max # of nested Strong/Emph
632 stateLastStrPos :: Maybe SourcePos, -- ^ Position after last str parsed
633 stateLastStrPos :: Maybe SourcePos, -- ^ Position after last str parsed
633 stateKeys :: KeyTable, -- ^ List of reference keys
634 stateKeys :: KeyTable, -- ^ List of reference keys
634 stateCitations :: [String], -- ^ List of available citations
635 stateCitations :: [String], -- ^ List of available citations
@@ -660,6 +661,7 @@ defaultParserState =
660 ParserState { stateParseRaw = False,
661 ParserState { stateParseRaw = False,
661 stateParserContext = NullState,
662 stateParserContext = NullState,
662 stateQuoteContext = NoQuote,
663 stateQuoteContext = NoQuote,
664+ stateMaxNestingLevel = 6,
663 stateLastStrPos = Nothing,
665 stateLastStrPos = Nothing,
664 stateKeys = M.empty,
666 stateKeys = M.empty,
665 stateCitations = [],
667 stateCitations = [],
src/Text/Pandoc/Readers/Markdown.hs+14−2
@@ -1041,8 +1041,20 @@ inlinesBetween start end =
1041 where inner = innerSpace <|> (notFollowedBy' whitespace >> inline)
1041 where inner = innerSpace <|> (notFollowedBy' whitespace >> inline)
1042 innerSpace = try $ whitespace >>~ notFollowedBy' end
1042 innerSpace = try $ whitespace >>~ notFollowedBy' end
1043
1043
1044+-- This is used to prevent exponential blowups for things like:
1045+-- a**a*a**a*a**a*a**a*a**a*a**a*a**
1046+nested :: GenParser Char ParserState a
1047+ -> GenParser Char ParserState a
1048+nested p = do
1049+ nestlevel <- stateMaxNestingLevel `fmap` getState
1050+ guard $ nestlevel > 0
1051+ updateState $ \st -> st{ stateMaxNestingLevel = stateMaxNestingLevel st - 1 }
1052+ res <- p
1053+ updateState $ \st -> st{ stateMaxNestingLevel = nestlevel }
1054+ return res
1055+
1044emph :: GenParser Char ParserState Inline
1056emph :: GenParser Char ParserState Inline
1045−emph = Emph `liftM`
1057+emph = Emph `fmap` nested
1046 (inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
1058 (inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
1047 where starStart = char '*' >> lookAhead nonspaceChar
1059 where starStart = char '*' >> lookAhead nonspaceChar
1048 starEnd = notFollowedBy' strong >> char '*'
1060 starEnd = notFollowedBy' strong >> char '*'
@@ -1050,7 +1062,7 @@ emph = Emph `liftM`
1050 ulEnd = notFollowedBy' strong >> char '_'
1062 ulEnd = notFollowedBy' strong >> char '_'
1051
1063
1052strong :: GenParser Char ParserState Inline
1064strong :: GenParser Char ParserState Inline
1053−strong = Strong `liftM`
1065+strong = Strong `liftM` nested
1054 (inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
1066 (inlinesBetween starStart starEnd <|> inlinesBetween ulStart ulEnd)
1055 where starStart = string "**" >> lookAhead nonspaceChar
1067 where starStart = string "**" >> lookAhead nonspaceChar
1056 starEnd = try $ string "**"
1068 starEnd = try $ string "**"