diff --git a/docs/changelog.md b/docs/changelog.md index 1f4307cda..c55c9dda5 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Remove legacy import needed only in Python 2 (#1403) * Fix typo that left the attribute `AdmonitionProcessor.content_indent` unset (#1404) +* Fix edge-case crash in `codehilite` with an empty `code` tag (#1405). * Improve and expand type annotations in the code base (#1401). ## [3.5.1] -- 2023-10-31 diff --git a/markdown/extensions/codehilite.py b/markdown/extensions/codehilite.py index 0114908f6..92e7d8f2b 100644 --- a/markdown/extensions/codehilite.py +++ b/markdown/extensions/codehilite.py @@ -270,8 +270,11 @@ def run(self, root: etree.Element) -> None: for block in blocks: if len(block) == 1 and block[0].tag == 'code': local_config = self.config.copy() + text = block[0].text + if text is None: + continue code = CodeHilite( - self.code_unescape(block[0].text), + self.code_unescape(text), tab_length=self.md.tab_length, style=local_config.pop('pygments_style', 'default'), **local_config diff --git a/tests/test_syntax/extensions/test_code_hilite.py b/tests/test_syntax/extensions/test_code_hilite.py index 0a41c4f76..2094203ae 100644 --- a/tests/test_syntax/extensions/test_code_hilite.py +++ b/tests/test_syntax/extensions/test_code_hilite.py @@ -21,7 +21,9 @@ from markdown.test_tools import TestCase from markdown.extensions.codehilite import CodeHiliteExtension, CodeHilite +from markdown import extensions, treeprocessors import os +import xml.etree.ElementTree as etree try: import pygments # noqa @@ -762,3 +764,22 @@ def testFormatterLangStrEmptyLang(self): ) ] ) + + def testDoesntCrashWithEmptyCodeTag(self): + expected = '

Hello

\n
' + self.assertMarkdownRenders( + '# Hello', + expected, + extensions=[CodeHiliteExtension(), _ExtensionThatAddsAnEmptyCodeTag()] + ) + + +class _ExtensionThatAddsAnEmptyCodeTag(extensions.Extension): + def extendMarkdown(self, md): + md.treeprocessors.register(_AddCodeTagTreeprocessor(), 'add-code-tag', 40) + + +class _AddCodeTagTreeprocessor(treeprocessors.Treeprocessor): + def run(self, root: etree.Element): + pre = etree.SubElement(root, 'pre') + etree.SubElement(pre, 'code')