git.iko.soy/typeable/pandoc
on master help sign in
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.

commitb42c48e91918388e6b8eaaba36f4521441128a00 authorJohn MacFarlane <jgm@berkeley.edu> dateWed 20 Apr 2011, 11:42 (16 years ago) parent4f526fc
3 files changed+22−6
src/Tests/Readers/Markdown.hs+3 src/Text/Pandoc/Readers/Markdown.hs+8−1 src/Text/Pandoc/Readers/RST.hs+11−5
src/Tests/Readers/Markdown.hs+3
@@ -47,6 +47,9 @@ tests = [ testGroup "inline code"
4747 , "indent followed by newline and indented text" =:
4848 "[^1]\n\n[^1]: my note\n \n in note\n"
4949 =?> para (note (para "my note" +++ para "in note"))
50+ , "recursive note" =:
51+ "[^1]\n\n[^1]: See [^1]\n"
52+ =?> para (note (para "See [^1]"))
5053 ]
5154 , testGroup "lhs"
5255 [ test (readMarkdown defaultParserState{stateLiterateHaskell = True})
src/Text/Pandoc/Readers/Markdown.hs+8−1
@@ -1187,7 +1187,14 @@ note = try $ do
11871187 let notes = stateNotes state
11881188 case lookup ref notes of
11891189 Nothing -> fail "note not found"
1190− Just raw -> liftM Note $ parseFromString parseBlocks raw
1190+ Just raw -> do
1191+ -- We temporarily empty the note list while parsing the note,
1192+ -- so that we don't get infinite loops with notes inside notes...
1193+ -- Note references inside other notes do not work.
1194+ updateState $ \st -> st{ stateNotes = [] }
1195+ contents <- parseFromString parseBlocks raw
1196+ updateState $ \st -> st{ stateNotes = notes }
1197+ return $ Note contents
11911198
11921199inlineNote :: GenParser Char ParserState Inline
11931200inlineNote = try $ do
src/Text/Pandoc/Readers/RST.hs+11−5
@@ -866,10 +866,16 @@ note = try $ do
866866 case lookup ref notes of
867867 Nothing -> fail "note not found"
868868 Just raw -> do
869+ -- We temporarily empty the note list while parsing the note,
870+ -- so that we don't get infinite loops with notes inside notes...
871+ -- Note references inside other notes are allowed in reST, but
872+ -- not yet in this implementation.
873+ updateState $ \st -> st{ stateNotes = [] }
869874 contents <- parseFromString parseBlocks raw
870− when (ref == "*" || ref == "#") $ do -- auto-numbered
871− -- delete the note so the next auto-numbered note
872− -- doesn't get the same contents:
873− let newnotes = deleteFirstsBy (==) notes [(ref,raw)]
874− updateState $ \st -> st{ stateNotes = newnotes }
875+ let newnotes = if (ref == "*" || ref == "#") -- auto-numbered
876+ -- delete the note so the next auto-numbered note
877+ -- doesn't get the same contents:
878+ then deleteFirstsBy (==) notes [(ref,raw)]
879+ else notes
880+ updateState $ \st -> st{ stateNotes = newnotes }
875881 return $ Note contents