Skip to content

Commit 30e0fe4

Browse files
committed
Fix merge conflicts
Merge branch 'master' into lang-name-in-class-using-pygments
2 parents c398584 + 1d37310 commit 30e0fe4

31 files changed

+272
-129
lines changed

.github/workflows/python.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ jobs:
99
runs-on: ${{ matrix.os }}
1010
strategy:
1111
matrix:
12-
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
12+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
1313
os:
14-
- ubuntu-20.04
14+
- ubuntu-latest
1515
- macos-latest
1616
- windows-latest
1717
steps:
18-
- uses: actions/checkout@v2
18+
- uses: actions/checkout@v4
1919
- name: Set up Python ${{ matrix.python-version }}
20-
uses: actions/setup-python@v2
20+
uses: actions/setup-python@v5
2121
with:
2222
python-version: ${{ matrix.python-version }}
2323
- name: Install dependencies

CHANGES.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
# python-markdown2 Changelog
22

3-
## python-markdown2 2.5.1 (not yet released)
3+
## python-markdown2 2.5.2 (not yet released)
4+
5+
- [pull #605] Add support for Python 3.13, drop EOL 3.8
6+
- [pull #607] Fix `middle-word-em` extra preventing strongs from being recognized (#606)
7+
- [pull #596] Add language to HTML output in pygments code blocks (#379)
8+
9+
10+
## python-markdown2 2.5.1
411

512
- [pull #590] Fix underscores within bold text getting emphasized (#589)
613
- [pull #591] Add Alerts extra
714
- [pull #595] Fix img alt text being processed as markdown (#594)
8-
- [pull #596] Add language to HTML output in pygments code blocks (#379)
15+
- [pull #598] Add `link-shortrefs` extra (#597)
16+
- [pull #600] Use urandom for SECRET_SALT
17+
- [pull #602] Fix XSS issue in safe mode (#601)
18+
- [pull #604] Fix XSS injection in image URLs (#603)
919

1020

1121
## python-markdown2 2.5.0

CONTRIBUTORS.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ Kishore (github.com/jk6521)
6060
Ircama (github.com/Ircama)
6161
Ankit Mahato (github.com/animator)
6262
Eric Dufresne (github.com/edufresne)
63+
Lyra Rebane (github.com/rebane2001)

lib/markdown2.py

Lines changed: 134 additions & 82 deletions
Large diffs are not rendered by default.

perf/gen_perf_cases.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ def _markdown_from_aspn_html(html):
104104
title = None
105105
escaped_href = href.replace('(', '\\(').replace(')', '\\)')
106106
if title is None:
107-
replacement = '[%s](%s)' % (content, escaped_href)
107+
replacement = '[{}]({})'.format(content, escaped_href)
108108
else:
109-
replacement = '[%s](%s "%s")' % (content, escaped_href,
109+
replacement = '[{}]({} "{}")'.format(content, escaped_href,
110110
title.replace('"', "'"))
111111
markdown = markdown[:start] + replacement + markdown[end:]
112112

perf/perf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def time_markdown_py(cases_dir, repeat):
3434
for i in range(repeat):
3535
start = clock()
3636
for path in glob(join(cases_dir, "*.text")):
37-
f = open(path, 'r')
37+
f = open(path)
3838
content = f.read()
3939
f.close()
4040
try:
@@ -59,7 +59,7 @@ def time_markdown2_py(cases_dir, repeat):
5959
for i in range(repeat):
6060
start = clock()
6161
for path in glob(join(cases_dir, "*.text")):
62-
f = open(path, 'r')
62+
f = open(path)
6363
content = f.read()
6464
f.close()
6565
markdowner.convert(content)

perf/strip_cookbook_data.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
from os.path import *
32
from pprint import pformat
43

perf/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def wrapper(*args, **kw):
3030
return func(*args, **kw)
3131
finally:
3232
total_time = clock() - start_time
33-
print("%s took %.3fs" % (func.__name__, total_time))
33+
print("{} took {:.3f}s".format(func.__name__, total_time))
3434
return wrapper
3535

3636
def hotshotit(func):

sandbox/wiki.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
import sys
32
import re
43
from os.path import *

setup.cfg

Lines changed: 0 additions & 2 deletions
This file was deleted.

setup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@
1818
License :: OSI Approved :: MIT License
1919
Programming Language :: Python
2020
Programming Language :: Python :: 3
21-
Programming Language :: Python :: 3.8
2221
Programming Language :: Python :: 3.9
2322
Programming Language :: Python :: 3.10
2423
Programming Language :: Python :: 3.11
2524
Programming Language :: Python :: 3.12
25+
Programming Language :: Python :: 3.13
2626
Operating System :: OS Independent
2727
Topic :: Software Development :: Libraries :: Python Modules
2828
Topic :: Software Development :: Documentation
@@ -32,7 +32,7 @@
3232

3333
extras_require = {
3434
"code_syntax_highlighting": ["pygments>=2.7.3"],
35-
"wavedrom": ["wavedrom; python_version>='3.7'"],
35+
"wavedrom": ["wavedrom"],
3636
"latex": ['latex2mathml; python_version>="3.8.1"'],
3737
}
3838
# nested listcomp to combine all optional extras into convenient "all" option
@@ -56,7 +56,7 @@
5656
]
5757
},
5858
description="A fast and complete Python implementation of Markdown",
59-
python_requires=">=3.8, <4",
59+
python_requires=">=3.9, <4",
6060
extras_require=extras_require,
6161
classifiers=classifiers.strip().split("\n"),
6262
long_description="""markdown2: A fast and complete Python implementation of Markdown.

test/markdown.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def is_block_level (tag) :
116116
(re.compile(">"), "&gt;"),
117117
(re.compile("\""), "&quot;")]
118118

119-
ENTITY_NORMALIZATION_EXPRESSIONS_SOFT = [ (re.compile("&(?!\#)"), "&amp;"),
119+
ENTITY_NORMALIZATION_EXPRESSIONS_SOFT = [ (re.compile(r"&(?!\#)"), "&amp;"),
120120
(re.compile("<"), "&lt;"),
121121
(re.compile(">"), "&gt;"),
122122
(re.compile("\""), "&quot;")]
@@ -325,7 +325,7 @@ def toxml(self):
325325
value = self.attribute_values[attr]
326326
value = self.doc.normalizeEntities(value,
327327
avoidDoubleNormalizing=True)
328-
buffer += ' %s="%s"' % (attr, value)
328+
buffer += ' {}="{}"'.format(attr, value)
329329

330330

331331
# Now let's actually append the children
@@ -672,7 +672,7 @@ def run (self, lines) :
672672
LINK_ANGLED_RE = BRK + r'\s*\(<([^\)]*)>\)' # [text](<url>)
673673
IMAGE_LINK_RE = r'\!' + BRK + r'\s*\(([^\)]*)\)' # ![alttxt](http://x.com/)
674674
REFERENCE_RE = BRK+ r'\s*\[([^\]]*)\]' # [Google][3]
675-
IMAGE_REFERENCE_RE = r'\!' + BRK + '\s*\[([^\]]*)\]' # ![alt text][2]
675+
IMAGE_REFERENCE_RE = r'\!' + BRK + r'\s*\[([^\]]*)\]' # ![alt text][2]
676676
NOT_STRONG_RE = r'( \* )' # stand-alone * or _
677677
AUTOLINK_RE = r'<(http://[^>]*)>' # <http://www.123.com>
678678
AUTOMAIL_RE = r'<([^> \!]*@[^> ]*)>' # <[email protected]>

test/test.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@ def setup():
2727
import pygments # noqa
2828
except ImportError:
2929
pygments_dir = join(top_dir, "deps", "pygments")
30-
if sys.version_info[0] <= 2:
31-
sys.path.insert(0, pygments_dir)
32-
else:
33-
sys.path.insert(0, pygments_dir + "3")
30+
sys.path.insert(0, pygments_dir + "3")
3431

3532
if __name__ == "__main__":
3633
logging.basicConfig()
@@ -42,7 +39,7 @@ def setup():
4239
try:
4340
mod = importlib.import_module(extra_lib)
4441
except ImportError:
45-
warnings.append("skipping %s tests ('%s' module not found)" % (extra_lib, extra_lib))
42+
warnings.append("skipping {} tests ('{}' module not found)".format(extra_lib, extra_lib))
4643
default_tags.append("-%s" % extra_lib)
4744
else:
4845
if extra_lib == 'pygments':
@@ -51,7 +48,7 @@ def setup():
5148
tag = "pygments<2.14"
5249
else:
5350
tag = "pygments>=2.14"
54-
warnings.append("skipping %s tests (pygments %s found)" % (tag, mod.__version__))
51+
warnings.append("skipping {} tests (pygments {} found)".format(tag, mod.__version__))
5552
default_tags.append("-%s" % tag)
5653

5754
retval = testlib.harness(testdir_from_ns=testdir_from_ns,

test/test_markdown2.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def generate_tests(cls):
152152
if exists(opts_path):
153153
try:
154154
with warnings.catch_warnings(record=True) as caught_warnings:
155-
opts = eval(open(opts_path, 'r').read())
155+
opts = eval(open(opts_path).read())
156156
for warning in caught_warnings:
157157
print("WARNING: loading %s generated warning: %s - lineno %d" % (opts_path, warning.message, warning.lineno), file=sys.stderr)
158158
except Exception:
@@ -335,7 +335,7 @@ def _markdown_email_link_sub(match):
335335
href, text = match.groups()
336336
href = _xml_escape_re.sub(_xml_escape_sub, href)
337337
text = _xml_escape_re.sub(_xml_escape_sub, text)
338-
return '<a href="%s">%s</a>' % (href, text)
338+
return '<a href="{}">{}</a>'.format(href, text)
339339

340340
def norm_html_from_html(html):
341341
"""Normalize (somewhat) Markdown'd HTML.

test/testall.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ def testall():
5353
# Don't support Python < 3.5
5454
continue
5555
ver_str = "%s.%s" % ver
56-
print("-- test with Python %s (%s)" % (ver_str, python))
56+
print("-- test with Python {} ({})".format(ver_str, python))
5757
assert ' ' not in python
5858

5959
env_args = 'MACOSX_DEPLOYMENT_TARGET= ' if sys.platform == 'darwin' else ''
6060

6161
proc = subprocess.Popen(
6262
# pass "-u" option to force unbuffered output
63-
"%s%s -u test.py -- -knownfailure" % (env_args, python),
63+
"{}{} -u test.py -- -knownfailure".format(env_args, python),
6464
shell=True, stderr=subprocess.PIPE
6565
)
6666

@@ -77,6 +77,6 @@ def testall():
7777

7878
for python, ver_str, warning in all_warnings:
7979
# now re-print all warnings to make sure they are seen
80-
print('-- warning raised by Python %s (%s) -- %s' % (ver_str, python, warning))
80+
print('-- warning raised by Python {} ({}) -- {}'.format(ver_str, python, warning))
8181

8282
testall()

test/testlib.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,8 @@ def wrapper(*args, **kw):
130130
finally:
131131
total_time = time.time() - start_time
132132
if total_time > max_time + tolerance:
133-
raise DurationError(('Test was too long (%.2f s)'
134-
% total_time))
133+
raise DurationError('Test was too long (%.2f s)'
134+
% total_time)
135135
return wrapper
136136

137137
return _timedtest
@@ -140,7 +140,7 @@ def wrapper(*args, **kw):
140140

141141
#---- module api
142142

143-
class Test(object):
143+
class Test:
144144
def __init__(self, ns, testmod, testcase, testfn_name,
145145
testsuite_class=None):
146146
self.ns = ns
@@ -439,7 +439,7 @@ def list_tests(testdir_from_ns, tags):
439439
if testfile.endswith(".pyc"):
440440
testfile = testfile[:-1]
441441
print("%s:" % t.shortname())
442-
print(" from: %s#%s.%s" % (testfile,
442+
print(" from: {}#{}.{}".format(testfile,
443443
t.testcase.__class__.__name__, t.testfn_name))
444444
wrapped = textwrap.fill(' '.join(t.tags()), WIDTH-10)
445445
print(" tags: %s" % _indent(wrapped, 8, True))
@@ -470,7 +470,7 @@ def __init__(self, stream):
470470

471471
def getDescription(self, test):
472472
if test._testlib_explicit_tags_:
473-
return "%s [%s]" % (test._testlib_shortname_,
473+
return "{} [{}]".format(test._testlib_shortname_,
474474
', '.join(test._testlib_explicit_tags_))
475475
else:
476476
return test._testlib_shortname_
@@ -514,7 +514,7 @@ def printErrorList(self, flavour, errors):
514514
self.stream.write("%s\n" % err)
515515

516516

517-
class ConsoleTestRunner(object):
517+
class ConsoleTestRunner:
518518
"""A test runner class that displays results on the console.
519519
520520
It prints out the names of tests as they are run, errors as they

test/tm-cases/issue601_xss.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>&lt;img src=# onerror="alert()"&gt;&lt;/p&gt;</p>

test/tm-cases/issue601_xss.opts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"safe_mode": "escape"}

test/tm-cases/issue601_xss.text

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<img src=# onerror="alert()"></p>

test/tm-cases/issue603_xss.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<p><img src="code&gt;&quot; onerror=alert()//&lt;/code" alt="" /></p>
2+
3+
<p><img src="&quot; onerror=alert()//" alt="" />
4+
<a href="#"></a>
5+
<img src="`&quot; onerror=alert()//`" alt="" />
6+
<img src="&lt;code&gt;&quot; onerror=alert()//&lt;code&gt;" alt="" /></p>

test/tm-cases/issue603_xss.opts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"safe_mode": "escape"}

test/tm-cases/issue603_xss.text

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
![](`" onerror=alert()//`)
2+
3+
4+
![][XSS]
5+
[][XSS]
6+
![][XSS2]
7+
![][XSS3]
8+
9+
10+
[XSS]: " onerror=alert()//
11+
[XSS2]: `" onerror=alert()//`
12+
[XSS3]: <code>" onerror=alert()//<code>

test/tm-cases/link_shortrefs.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<p><a href="https://www.python.org">Python</a></p>
2+
3+
<p>abc <a href="https://www.python.org">Python</a> def</p>
4+
5+
<p><a href="https://www.python.org">Python</a>s</p>
6+
7+
<p><a href="https://www.python.org">Python</a></p>
8+
9+
<p><a href="https://www.python.org">Python</a>with<em>more</em>text</p>
10+
11+
<p>[NoLink]</p>

test/tm-cases/link_shortrefs.opts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extras": ["link-shortrefs"]}

test/tm-cases/link_shortrefs.tags

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extras link-shortrefs

test/tm-cases/link_shortrefs.text

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[Python]
2+
3+
abc [Python] def
4+
5+
[Python]s
6+
7+
[Python][]
8+
9+
[Python]with_more_text
10+
11+
[NoLink]
12+
13+
[Python]: https://www.python.org
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<p>Double variants:</p>
2+
3+
<p><strong>one_two_three</strong></p>
4+
5+
<p><strong><em>one_two_three</em></strong></p>
6+
7+
<p><em><strong>one_two_three</strong></em></p>
8+
9+
<p><strong><em>one_two_three</em></strong></p>
10+
11+
<p>Single variants:</p>
12+
13+
<p><em>one_two_three</em></p>
14+
15+
<p><em>one_two_three</em></p>
16+
17+
<p><em>one*two*three</em></p>
18+
19+
<p><em>one<em>two</em>three</em></p>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"extras": {"middle-word-em": False}}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Double variants:
2+
3+
**one_two_three**
4+
5+
***one_two_three***
6+
7+
_**one_two_three**_
8+
9+
**_one_two_three_**
10+
11+
Single variants:
12+
13+
*one_two_three*
14+
15+
_one_two_three_
16+
17+
_one*two*three_
18+
19+
*one*two*three*

0 commit comments

Comments
 (0)