diff options
author | John MacFarlane <jgm@berkeley.edu> | 2011-04-20 11:42:27 -0700 |
---|---|---|
committer | John MacFarlane <jgm@berkeley.edu> | 2011-04-20 11:42:27 -0700 |
commit | b42c48e91918388e6b8eaaba36f4521441128a00 (patch) | |
tree | ed5c86a7c12659562600d448d536da188b3f07ad /src/Text | |
parent | 4f526fc5218ccb4a7b40c17adb2d85ba82a08d2f (diff) | |
download | pandoc-b42c48e91918388e6b8eaaba36f4521441128a00.tar.gz |
Disallow notes within notes in reST and markdown.
These previously caused infinite looping and stack overflows.
For example:
[^1]
[^1]: See [^1]
Note references are allowed in reST notes, so this isn't a full
implementation of reST. That can come later. For now we need to
prevent the stack overflows.
Partially resolves Issue #297.
Diffstat (limited to 'src/Text')
-rw-r--r-- | src/Text/Pandoc/Readers/Markdown.hs | 9 | ||||
-rw-r--r-- | src/Text/Pandoc/Readers/RST.hs | 16 |
2 files changed, 19 insertions, 6 deletions
diff --git a/src/Text/Pandoc/Readers/Markdown.hs b/src/Text/Pandoc/Readers/Markdown.hs index d284fb25e..1b408dcb2 100644 --- a/src/Text/Pandoc/Readers/Markdown.hs +++ b/src/Text/Pandoc/Readers/Markdown.hs @@ -1187,7 +1187,14 @@ note = try $ do let notes = stateNotes state case lookup ref notes of Nothing -> fail "note not found" - Just raw -> liftM Note $ parseFromString parseBlocks raw + Just raw -> do + -- We temporarily empty the note list while parsing the note, + -- so that we don't get infinite loops with notes inside notes... + -- Note references inside other notes do not work. + updateState $ \st -> st{ stateNotes = [] } + contents <- parseFromString parseBlocks raw + updateState $ \st -> st{ stateNotes = notes } + return $ Note contents inlineNote :: GenParser Char ParserState Inline inlineNote = try $ do diff --git a/src/Text/Pandoc/Readers/RST.hs b/src/Text/Pandoc/Readers/RST.hs index 04bb33023..844b4e5b8 100644 --- a/src/Text/Pandoc/Readers/RST.hs +++ b/src/Text/Pandoc/Readers/RST.hs @@ -866,10 +866,16 @@ note = try $ do case lookup ref notes of Nothing -> fail "note not found" Just raw -> do + -- We temporarily empty the note list while parsing the note, + -- so that we don't get infinite loops with notes inside notes... + -- Note references inside other notes are allowed in reST, but + -- not yet in this implementation. + updateState $ \st -> st{ stateNotes = [] } contents <- parseFromString parseBlocks raw - when (ref == "*" || ref == "#") $ do -- auto-numbered - -- delete the note so the next auto-numbered note - -- doesn't get the same contents: - let newnotes = deleteFirstsBy (==) notes [(ref,raw)] - updateState $ \st -> st{ stateNotes = newnotes } + let newnotes = if (ref == "*" || ref == "#") -- auto-numbered + -- delete the note so the next auto-numbered note + -- doesn't get the same contents: + then deleteFirstsBy (==) notes [(ref,raw)] + else notes + updateState $ \st -> st{ stateNotes = newnotes } return $ Note contents |