Barry Warsaw pushed to branch master at mailman / Mailman
Commits: 1ff113e9 by Mark Sapiro at 2016-07-18T21:28:07-07:00 Improved email address validation and added tests. - - - - - 7bc90be6 by Mark Sapiro at 2016-07-19T04:45:13+00:00 Fix failure to change copied name :( - - - - - 2 changed files: - src/mailman/email/validate.py - src/mailman/model/tests/test_address.py Changes: ===================================== src/mailman/email/validate.py ===================================== --- a/src/mailman/email/validate.py +++ b/src/mailman/email/validate.py @@ -26,10 +26,11 @@ from mailman.utilities.email import split_email from zope.interface import implementer -# What other characters should be disallowed? -_badchars = re.compile(r'[][()<>|:;^,\\"\000-\037\177-\377]') -# Strictly speaking, some of the above are allowed in quoted local parts, but -# this can open the door to certain web exploits so we don't allow them. +# What other characters should be allowed? +_valid_local = re.compile("[-0-9a-z!#$%&'*+./=?@_`{}~]", re.IGNORECASE) +# Strictly speaking, both ^ and | are allowed and others are allowed in quoted +# local parts, but this can open the door to certain web exploits so we don't +# allow them. _valid_domain = re.compile('[-a-z0-9]', re.IGNORECASE) # These are the only characters allowed in domain parts. @@ -41,11 +42,11 @@ class Validator: def is_valid(self, email): """See `IEmailValidator`.""" - if not email or ' ' in email: - return False - if _badchars.search(email): + if not email: return False user, domain_parts = split_email(email) + if not user or len(_valid_local.sub('', user)) > 0: + return False # Local, unqualified addresses are not allowed. if not domain_parts: return False ===================================== src/mailman/model/tests/test_address.py ===================================== --- a/src/mailman/model/tests/test_address.py +++ b/src/mailman/model/tests/test_address.py @@ -40,6 +40,42 @@ class TestAddress(unittest.TestCase): self.assertRaises(InvalidEmailAddressError, Address, 'not_a_valid_email_string', '') + def test_no_local_email_string_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, '@example.com', '') + + def test_space_in_email_string_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'us e...@example.com', '') + + def test_non_ascii_email_local_part_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'us\x...@example.com', '') + + def test_non_ascii_email_domain_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'user@\xe9xample.com', '') + + def test_leading_hyphen_email_domain_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'user@example.-com', '') + + def test_empty_part_email_domain_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'u...@example..com', '') + + def test_bad_ascii_email_domain_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'user@x_example.com', '') + + def test_high_unicode_email_local_part_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'us\u01...@example.com', '') + + def test_high_unicode_email_domain_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'user@\u0117xample.com', '') + def test_local_part_differs_only_by_case(self): with self.assertRaises(ExistingAddressError) as cm: self._usermgr.create_address('fper...@example.com') View it on GitLab: https://gitlab.com/mailman/mailman/compare/a3e6f5952f262557d7279cad372d2f4f532d9b36...7bc90be6613f88042a8fcffbf06d7daa049c4cda
_______________________________________________ Mailman-checkins mailing list Mailman-checkins@python.org Unsubscribe: https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org