diff options
Diffstat (limited to 'markdown')
-rw-r--r-- | markdown/blockprocessors.py | 4 | ||||
-rw-r--r-- | markdown/inlinepatterns.py | 4 | ||||
-rw-r--r-- | markdown/serializers.py | 11 | ||||
-rw-r--r-- | markdown/util.py | 11 |
4 files changed, 23 insertions, 7 deletions
diff --git a/markdown/blockprocessors.py b/markdown/blockprocessors.py index d2c9cd3..378c7c7 100644 --- a/markdown/blockprocessors.py +++ b/markdown/blockprocessors.py @@ -259,14 +259,14 @@ class CodeBlockProcessor(BlockProcessor): code = sibling[0] block, theRest = self.detab(block) code.text = util.AtomicString( - '%s\n%s\n' % (code.text, block.rstrip()) + '%s\n%s\n' % (code.text, util.code_escape(block.rstrip())) ) else: # This is a new codeblock. Create the elements and insert text. pre = util.etree.SubElement(parent, 'pre') code = util.etree.SubElement(pre, 'code') block, theRest = self.detab(block) - code.text = util.AtomicString('%s\n' % block.rstrip()) + code.text = util.AtomicString('%s\n' % util.code_escape(block.rstrip())) if theRest: # This block contained unindented line(s) after the first indented # line. Insert these lines as the first block of the master blocks diff --git a/markdown/inlinepatterns.py b/markdown/inlinepatterns.py index 83edf4b..8d49d07 100644 --- a/markdown/inlinepatterns.py +++ b/markdown/inlinepatterns.py @@ -158,7 +158,7 @@ AUTOMAIL_RE = r'<([^> \!]*@[^> ]*)>' HTML_RE = r'(\<([a-zA-Z/][^\>]*?|\!--.*?--)\>)' # & -ENTITY_RE = r'(&[\#a-zA-Z0-9]*;)' +ENTITY_RE = r'(&(?:\#[0-9]+|[a-zA-Z0-9]+);)' # two spaces at end of line LINE_BREAK_RE = r' \n' @@ -369,7 +369,7 @@ class BacktickInlineProcessor(InlineProcessor): def handleMatch(self, m, data): if m.group(3): el = util.etree.Element(self.tag) - el.text = util.AtomicString(m.group(3).strip()) + el.text = util.AtomicString(util.code_escape(m.group(3).strip())) return el, m.start(0), m.end(0) else: return m.group(1).replace('\\\\', self.ESCAPED_BSLASH), m.start(0), m.end(0) diff --git a/markdown/serializers.py b/markdown/serializers.py index 308cf7a..3cfa6bb 100644 --- a/markdown/serializers.py +++ b/markdown/serializers.py @@ -41,6 +41,7 @@ from __future__ import absolute_import from __future__ import unicode_literals from xml.etree.ElementTree import ProcessingInstruction from . import util +import re ElementTree = util.etree.ElementTree QName = util.etree.QName if hasattr(util.etree, 'test_comment'): # pragma: no cover @@ -52,6 +53,7 @@ __all__ = ['to_html_string', 'to_xhtml_string'] HTML_EMPTY = ("area", "base", "basefont", "br", "col", "frame", "hr", "img", "input", "isindex", "link", "meta", "param") +RE_AMP = re.compile(r'&(?!(?:\#[0-9]+|[0-9a-z]+);)', re.I) try: HTML_EMPTY = set(HTML_EMPTY) @@ -72,7 +74,8 @@ def _escape_cdata(text): # shorter than 500 character, or so. assume that's, by far, # the most common case in most applications. if "&" in text: - text = text.replace("&", "&") + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) if "<" in text: text = text.replace("<", "<") if ">" in text: @@ -86,7 +89,8 @@ def _escape_attrib(text): # escape attribute value try: if "&" in text: - text = text.replace("&", "&") + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) if "<" in text: text = text.replace("<", "<") if ">" in text: @@ -104,7 +108,8 @@ def _escape_attrib_html(text): # escape attribute value try: if "&" in text: - text = text.replace("&", "&") + # Only replace & when not part of an entity + text = RE_AMP.sub('&', text) if "<" in text: text = text.replace("<", "<") if ">" in text: diff --git a/markdown/util.py b/markdown/util.py index aeb7818..b40c010 100644 --- a/markdown/util.py +++ b/markdown/util.py @@ -140,6 +140,17 @@ def parseBoolValue(value, fail_on_errors=True, preserve_none=False): raise ValueError('Cannot parse bool value: %r' % value) +def code_escape(text): + """Escape code.""" + if "&" in text: + text = text.replace("&", "&") + if "<" in text: + text = text.replace("<", "<") + if ">" in text: + text = text.replace(">", ">") + return text + + def deprecated(message): """ Raise a DeprecationWarning when wrapped function/method is called. |