diff --git a/.spell-dict b/.spell-dict index 114e4b237..eed0f67b5 100644 --- a/.spell-dict +++ b/.spell-dict @@ -132,6 +132,7 @@ Treeprocessors tuple tuples unescape +unescaping unittest unordered untrusted diff --git a/docs/change_log/release-3.3.md b/docs/change_log/release-3.3.md index 752564d64..e4bb5c326 100644 --- a/docs/change_log/release-3.3.md +++ b/docs/change_log/release-3.3.md @@ -55,6 +55,7 @@ The following bug fixes are included in the 3.3 release: * Fix issues with complex emphasis (#979). * Limitations of `attr_list` extension are Documented (#965). +* Fix unescaping of HTML characters `<>` in CodeHilite (#990). [spec]: https://www.w3.org/TR/html5/text-level-semantics.html#the-code-element [fenced_code]: ../extensions/fenced_code_blocks.md diff --git a/markdown/extensions/codehilite.py b/markdown/extensions/codehilite.py index 915dfcf41..9eed561fc 100644 --- a/markdown/extensions/codehilite.py +++ b/markdown/extensions/codehilite.py @@ -225,9 +225,11 @@ class HiliteTreeprocessor(Treeprocessor): def code_unescape(self, text): """Unescape code.""" - text = text.replace("&", "&") text = text.replace("<", "<") text = text.replace(">", ">") + # Escaped '&' should be replaced at the end to avoid + # conflicting with < and >. + text = text.replace("&", "&") return text def run(self, root): diff --git a/tests/test_syntax/extensions/test_code_hilite.py b/tests/test_syntax/extensions/test_code_hilite.py index b60c483b1..8d5512d2f 100644 --- a/tests/test_syntax/extensions/test_code_hilite.py +++ b/tests/test_syntax/extensions/test_code_hilite.py @@ -564,6 +564,29 @@ def testDoubleEscape(self): extensions=['codehilite'] ) + def testEntitiesIntact(self): + if has_pygments: + expected = ( + '
'
+ ''
+ '< < and > >'
+ '\n'
+ '< < and > >\n'
+ ''
+ )
+ self.assertMarkdownRenders(
+ (
+ '\t:::text\n'
+ '\t< < and > >'
+ ),
+ expected,
+ extensions=['codehilite']
+ )
+
def testHighlightAmps(self):
if has_pygments:
expected = (