Skip to content

Commit 9aa4586

Browse files
authored
Improve email address validation for Automatic Links
1 parent 850b8a5 commit 9aa4586

File tree

3 files changed

+68
-4
lines changed

3 files changed

+68
-4
lines changed

docs/change_log/index.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ Python-Markdown Change Log
66
Under development: version 3.3.5 (a bug-fix release).
77

88
* Make the `slugify_unicode` function not remove diacritical marks (#1118).
9-
* Fix `[toc]` detection when used with `nl2br` extension (#1160)
10-
* Re-use compiled regex for block level checks (#1169)
9+
* Fix `[toc]` detection when used with `nl2br` extension (#1160).
10+
* Re-use compiled regex for block level checks (#1169).
1111
* Don't process shebangs in fenced code blocks when using CodeHilite (#1156).
12+
* Improve email address validation for Automatic Links (#1165).
1213

1314
Feb 24, 2021: version 3.3.4 (a bug-fix release).
1415

markdown/inlinepatterns.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ def build_inlinepatterns(md, **kwargs):
160160
AUTOLINK_RE = r'<((?:[Ff]|[Hh][Tt])[Tt][Pp][Ss]?://[^<>]*)>'
161161

162162
163-
AUTOMAIL_RE = r'<([^<> !]*@[^@<> ]*)>'
163+
AUTOMAIL_RE = r'<([^<> !]+@[^@<> ]+)>'
164164

165165
# <...>
166-
HTML_RE = r'(<([a-zA-Z/][^<>]*|!--(?:(?!<!--|-->).)*--)>)'
166+
HTML_RE = r'(<(\/?[a-zA-Z][^<>@ ]*( [^<>]*)?|!--(?:(?!<!--|-->).)*--)>)'
167167

168168
# "&#38;" (decimal) or "&#x26;" (hex) or "&amp;" (named)
169169
ENTITY_RE = r'(&(?:\#[0-9]+|\#x[0-9a-fA-F]+|[a-zA-Z0-9]+);)'
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"""
2+
Python Markdown
3+
4+
A Python implementation of John Gruber's Markdown.
5+
6+
Documentation: https://python-markdown.github.io/
7+
GitHub: https://github.com/Python-Markdown/markdown/
8+
PyPI: https://pypi.org/project/Markdown/
9+
10+
Started by Manfred Stienstra (http://www.dwerg.net/).
11+
Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
12+
Currently maintained by Waylan Limberg (https://github.com/waylan),
13+
Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
14+
15+
Copyright 2007-2021 The Python Markdown Project (v. 1.7 and later)
16+
Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
17+
Copyright 2004 Manfred Stienstra (the original version)
18+
19+
License: BSD (see LICENSE.md for details).
20+
"""
21+
22+
from markdown.test_tools import TestCase
23+
24+
25+
class TestAutomaticLinks(TestCase):
26+
27+
def test_email_address(self):
28+
self.assertMarkdownRenders(
29+
'asdfasdfadsfasd <[email protected]> or you can say ',
30+
'<p>asdfasdfadsfasd <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#117;&#114;'
31+
'&#105;&#64;&#102;&#114;&#101;&#101;&#119;&#105;&#115;&#100;&#111;&#109;&#46;&#111;&#114;'
32+
'&#103;">&#121;&#117;&#114;&#105;&#64;&#102;&#114;&#101;&#101;&#119;&#105;&#115;&#100;'
33+
'&#111;&#109;&#46;&#111;&#114;&#103;</a> or you can say </p>'
34+
)
35+
36+
def test_mailto_email_address(self):
37+
self.assertMarkdownRenders(
38+
'instead <mailto:[email protected]>',
39+
'<p>instead <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#121;&#117;&#114;&#105;&#64;'
40+
'&#102;&#114;&#101;&#101;&#119;&#105;&#115;&#100;&#111;&#109;&#46;&#111;&#114;&#103;">'
41+
'&#121;&#117;&#114;&#105;&#64;&#102;&#114;&#101;&#101;&#119;&#105;&#115;&#100;&#111;&#109;'
42+
'&#46;&#111;&#114;&#103;</a></p>'
43+
)
44+
45+
def test_email_address_with_ampersand(self):
46+
self.assertMarkdownRenders(
47+
48+
'<p><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#98;&#111;&#98;&#38;&#115;&#117;&#101;'
49+
'&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;">&#98;&#111;&#98;&amp;'
50+
'&#115;&#117;&#101;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;</a></p>'
51+
)
52+
53+
def test_invalid_email_address_local_part(self):
54+
self.assertMarkdownRenders(
55+
'Missing local-part <@domain>',
56+
'<p>Missing local-part &lt;@domain&gt;</p>'
57+
)
58+
59+
def test_invalid_email_address_domain(self):
60+
self.assertMarkdownRenders(
61+
'Missing domain <local-part@>',
62+
'<p>Missing domain &lt;local-part@&gt;</p>'
63+
)

0 commit comments

Comments
 (0)