markdown: Parsing >>>>>>… takes quadratic time and eventually crashes with recursion error
>>> import markdown, timeit
>>> num, dur = timeit.Timer(lambda: markdown.markdown(">" * 100)).autorange(); dur / num
0.004344235559692607
>>> num, dur = timeit.Timer(lambda: markdown.markdown(">" * 200)).autorange(); dur / num
0.016907797248859425
>>> num, dur = timeit.Timer(lambda: markdown.markdown(">" * 300)).autorange(); dur / num
0.05682634799741208
>>> markdown.markdown(">" * 331)
…
RecursionError: maximum recursion depth exceeded while calling a Python object
Same results in 3.0.1 and master.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 18 (12 by maintainers)
Commits related to this issue
- Limit depth of blockquotes using Python's recursion limit. If the Python stack comes within 100 frames of the recursion limit, then the nesting limit of blockquotes is met. Any remaining text, includ... — committed to waylan/markdown by waylan 4 years ago
- Limit depth of blockquotes using Python's recursion limit. (#991) If the Python stack comes within 100 frames of the recursion limit, then the nesting limit of blockquotes is met. Any remaining text... — committed to Python-Markdown/markdown by waylan 4 years ago
However, if I do this:
then my times are:
<del>The difference is negligible.</del> However, the example which counts up (to the max) is slower (relatively) that the example which counts down (the stack) for smaller size documents. As smaller documents are the norm, I think that is probably the more sensible way to go.
Whoops, my first attempt at both had the line which called the code commented out. I have since edited this comment and the last one to provide accurate results. The previous solution is noticeably better than this one.
Python-Markdown does not require a space between
>
s too: