diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/email/validate.py | 15 | ||||
| -rw-r--r-- | src/mailman/model/tests/test_address.py | 36 |
2 files changed, 44 insertions, 7 deletions
diff --git a/src/mailman/email/validate.py b/src/mailman/email/validate.py index 3d80b3a51..99371d9e5 100644 --- 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 diff --git a/src/mailman/model/tests/test_address.py b/src/mailman/model/tests/test_address.py index 896310796..3336dcea6 100644 --- 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 er@example.com', '') + + def test_non_ascii_email_local_part_raises_exception(self): + self.assertRaises(InvalidEmailAddressError, + Address, 'us\xe9r@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, 'user@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\u0117r@example.com', '') + + def test_non_ascii_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('fperson@example.com') |
