emails: refuse non standard user part in email addresses validation (#48679)

This commit is contained in:
Thomas NOËL 2020-11-20 01:32:23 +01:00 committed by Frédéric Péters
parent e6b5b3dd31
commit 44b27d2164
2 changed files with 23 additions and 8 deletions

View File

@ -294,10 +294,11 @@ def test_emailwidget():
req.form = {}
assert widget.parse() is None
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': 'foo@localhost'})
assert not widget.has_error()
assert widget.parse() == 'foo@localhost'
for good_email in ('foo@localhost', 'foo.bar@localhost', 'foo+bar@localhost', 'foo_bar@localhost'):
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': good_email})
assert not widget.has_error()
assert widget.parse() == good_email
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': 'foo'})
@ -311,6 +312,10 @@ def test_emailwidget():
mock_form_submission(req, widget, {'test': 'foo@localhost..localdomain'})
assert widget.has_error()
widget = EmailWidget('test')
mock_form_submission(req, widget, {'test': 'foö@localhost'})
assert widget.has_error()
def test_date_widget():
widget = DateWidget('test')

View File

@ -888,6 +888,10 @@ class FileWithPreviewWidget(CompositeWidget):
class EmailWidget(StringWidget):
HTML_TYPE = 'email'
user_part_re = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*\Z" # dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"\Z)', # quoted-string
re.IGNORECASE)
def __init__(self, *args, **kwargs):
StringWidget.__init__(self, *args, **kwargs)
@ -908,13 +912,19 @@ class EmailWidget(StringWidget):
# basic tests first
if not '@' in self.value[1:-1]:
self.error = _('must be a valid email address')
elif self.value[0] != '"' and ' ' in self.value:
return
if self.value[0] != '"' and ' ' in self.value:
self.error = _('must be a valid email address')
elif self.value[0] != '"' and self.value.count('@') != 1:
return
if self.value[0] != '"' and self.value.count('@') != 1:
self.error = _('must be a valid email address')
elif get_cfg('emails', {}).get('check_domain_with_dns', True):
return
user_part, domain = self.value.rsplit('@', 1)
if not self.user_part_re.match(user_part):
self.error = _('must be a valid email address')
return
if get_cfg('emails', {}).get('check_domain_with_dns', True):
# testing for domain existence
domain = self.value.split('@')[-1]
if [x for x in domain.split('.') if not x]:
# empty parts in domain, ex: @example..net, or
# @.example.net