Skip to content

fix: reset _escape_table and _code_table on each convert() call (closes #763) - #768

Open
HongTin2104 wants to merge 2 commits into
trentm:masterfrom
HongTin2104:fix/763-reset-escape-code-tables
Open

HongTin2104 wants to merge 2 commits into
trentm:masterfrom
HongTin2104:fix/763-reset-escape-code-tables

Conversation

@HongTin2104

Copy link
Copy Markdown

Summary

Reusing a Markdown() instance was retaining entries in _escape_table and _code_table across documents. These tables grew with each call, causing two problems:

Wrong output: A backslash before a URL that appeared in an earlier document was silently dropped, because the URL hash was already in _escape_table from that earlier call.

Quadratic slowdown: _escape_table and _code_table accumulated every URL and code span ever seen. With 40 documents of 200 links and 200 code spans each the 40th document took ~37× longer than the 1st.

Root cause

reset() cleared urls, titles, html_blocks, html_spans, list_level, and extras, but never touched _escape_table or _code_table.

Fix

Extract the table initialisation from __init__ into _reset_tables() and call it from both __init__ and reset(). The call in reset() is placed before _setup_extras() because the middle-word-em extra reads _escape_table.

The convenience function markdown2.markdown() is unaffected (it creates a new instance per call).

Verification

import markdown2
md = markdown2.Markdown()
md.convert('[a link](https://example.com/page)')
print(md.convert(r'Type \https://example.com/page to see it.'))
# Before: <p>Type https://example.com/page to see it.</p>
# After:  <p>Type \https://example.com/page to see it.</p>  (matches a fresh instance)

Added test/test_reuse_instance.py with 3 tests: backslash escape correctness, code span isolation, and a performance guard.

Closes #763

Reusing a Markdown() instance was retaining entries in _escape_table
and _code_table across documents. These tables grew with each call,
causing quadratic slowdown and incorrect output: a backslash before a
URL seen in an earlier document was silently dropped because the URL
hash was already in _escape_table.

Fix: extract the table initialisation into _reset_tables() and call it
from both __init__() and reset(). The call in reset() is placed before
_setup_extras() because the middle-word-em extra reads _escape_table.

Closes trentm#763
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reused Markdown instance keeps link URLs and code spans from earlier documents

1 participant