Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/python.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
os:
- ubuntu-latest
- macos-latest
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- [pull #692] Fix XSS from code spans in link titles (#691)
- [pull #695] Fix XSS issue from incomplete tags with no attributes (#694)
- [pull #700] Fix XSS from code spans in image alt text (#699)
- [pull #701] Allow boolean attribute syntax in `markdown-in-html` extra


## python-markdown2 2.5.5
Expand Down
14 changes: 8 additions & 6 deletions lib/markdown2.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,9 @@
* link-shortrefs: allow shortcut reference links, not followed by `[]` or
a link label.
* markdown-file-links: Replace links to `.md` files with `.html` links
* markdown-in-html: Allow the use of `markdown="1"` in a block HTML tag to
have markdown processing be done on its contents. Similar to
* markdown-in-html: Allow the use of `markdown="1"` or simply a `markdown` boolean
attribute in a block HTML tag to have markdown processing be done on its
contents. Similar to
<http://michelf.com/projects/php-markdown/extra/#markdown-attr> but with
some limitations.
* metadata: Extract metadata from a leading '---'-fenced block.
Expand Down Expand Up @@ -903,7 +904,8 @@ def _detab(self, text: str) -> str:
re.X | re.M)

_html_markdown_attr_re = re.compile(
r'''\s+markdown=("1"|'1')''')
# markdown attr, with optional assignment to true, must be followed by whitespace/boundary/closing tag chars
r'''\s+markdown(?:="1"|='1'|=1)?(?![^\s/>\b])''')
def _hash_html_block_sub(
self,
match: Union[re.Match[str], str],
Expand All @@ -927,20 +929,20 @@ def _hash_html_block_sub(

if raw and self.safe_mode:
html = self._sanitize_html(html)
elif 'markdown-in-html' in self.extras and 'markdown=' in html:
elif 'markdown-in-html' in self.extras and 'markdown' in html:
first_line = html.split('\n', 1)[0]
m = self._html_markdown_attr_re.search(first_line)
if m:
lines = html.split('\n')
# if MD is on same line as opening tag then split across two lines
lines = list(filter(None, (re.split(r'(.*?<%s.*markdown=.*?>)' % tag, lines[0])))) + lines[1:]
lines = list(filter(None, (re.split(r'(.*?<%s.*markdown.*?>)' % tag, lines[0])))) + lines[1:]
# if MD on same line as closing tag, split across two lines
lines = lines[:-1] + list(filter(None, re.split(r'(\s*?</%s>.*?$)' % tag, lines[-1])))
# extract key sections of the match
first_line = lines[0]
middle = '\n'.join(lines[1:-1])
last_line = lines[-1]
# remove `markdown="1"` attr from tag
# remove `markdown="1"` or `markdown` attr from tag
first_line = first_line[:m.start()] + first_line[m.end():]
# hash the HTML segments to protect them
f_key = _hash_text(first_line)
Expand Down
18 changes: 18 additions & 0 deletions test/tm-cases/markdown_in_html.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,21 @@ <h1 id="veggies">Veggies</h1>
<td markdown="1">This is *true* markdown text.</td>
</tr>
</table>

<h2 id="also-allowed">Also allowed</h2>

<div>

<p>Markdown attr <em>without</em> a truthy assignment, for your convenience</p>

</div>

<div class="abcdef">

<p>Mix it with other attrs, <em>why don't you?</em></p>

</div>

<div my_markdown_attr>
The check is smarter than `if 'markdown' in text`. This is invalid
</div>
17 changes: 16 additions & 1 deletion test/tm-cases/markdown_in_html.text
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ And a paragraph
And **this**.
</div>

<section markdown="1">
<section markdown='1'>
And even **this** in an HTML5 block tag.
</section>

Expand All @@ -33,3 +33,18 @@ And even **this** in an HTML5 block tag.
<td markdown="1">This is *true* markdown text.</td>
</tr>
</table>


## Also allowed

<div markdown>
Markdown attr *without* a truthy assignment, for your convenience
</div>

<div markdown class="abcdef">
Mix it with other attrs, _why don't you?_
</div>

<div my_markdown_attr>
The check is smarter than `if 'markdown' in text`. This is invalid
</div>
5 changes: 4 additions & 1 deletion test/tm-cases/markdown_in_html.toc_html
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,8 @@
<ul>
<li><a href="#this-too">This <strong>too</strong>.</a></li>
</ul></li>
<li><a href="#veggies">Veggies</a></li>
<li><a href="#veggies">Veggies</a>
<ul>
<li><a href="#also-allowed">Also allowed</a></li>
</ul></li>
</ul>
Loading