Ticket #4833: 4833-3.diff

File 4833-3.diff, 3.5 KB (added by claudep, 4 years ago)

Make idn validation also pass

  • django/core/validators.py

    diff --git a/django/core/validators.py b/django/core/validators.py
    index 51ea82f..ec6ace8 100644
    a b def validate_integer(value): 
    138138        raise ValidationError('')
    139139
    140140class EmailValidator(RegexValidator):
     141    """
     142    EmailValidator takes a tuple of regexes on init, one for user part and one
     143    for domain part
     144    """
     145    domain_whitelist = ['localhost']
    141146
    142147    def __call__(self, value):
    143         try:
    144             super(EmailValidator, self).__call__(value)
    145         except ValidationError, e:
    146             # Trivial case failed. Try for possible IDN domain-part
    147             if value and u'@' in value:
    148                 parts = value.split(u'@')
     148        if value and u'@' in value:
     149            user_part, domain_part = value.split(u'@', 1)
     150            res = self.regex[0].search(smart_unicode(user_part))
     151            if not self.regex[0].search(smart_unicode(user_part)):
     152                raise ValidationError(self.message, code=self.code)
     153            if (not smart_unicode(domain_part) in self.domain_whitelist and
     154                    not self.regex[1].search(smart_unicode(domain_part))):
     155                # Try for possible IDN domain-part
    149156                try:
    150                     parts[-1] = parts[-1].encode('idna')
     157                    domain_part = domain_part.encode('idna')
     158                    if not self.regex[1].search(smart_unicode(domain_part)):
     159                        raise ValidationError(self.message, code=self.code)
     160                    else:
     161                        return
    151162                except UnicodeError:
    152                     raise e
    153                 super(EmailValidator, self).__call__(u'@'.join(parts))
    154             else:
    155                 raise
     163                    pass
     164                raise ValidationError(self.message, code=self.code)
     165        else:
     166            raise ValidationError(self.message, code=self.code)
    156167
    157 email_re = re.compile(
    158     r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    159     r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    160     r')@((?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)'  # domain
    161     r'|\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$', re.IGNORECASE)  # literal form, ipv4 address (SMTP 4.1.3)
     168email_re = (
     169    re.compile(
     170        r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*$"  # dot-atom
     171        r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"$)', # quoted-string
     172        re.IGNORECASE
     173    ),
     174    re.compile(
     175        r'(^(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$)'  # domain
     176        r'|^\[(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}\]$', # literal form, ipv4 address (SMTP 4.1.3)
     177        re.IGNORECASE
     178    )
     179)
    162180validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')
    163181
    164182slug_re = re.compile(r'^[-\w]+$')
  • tests/modeltests/validators/tests.py

    diff --git a/tests/modeltests/validators/tests.py b/tests/modeltests/validators/tests.py
    index 9e254b9..ed8bdfb 100644
    a b TEST_DATA = ( 
    2323    (validate_email, 'email@here.com', None),
    2424    (validate_email, 'weirder-email@here.and.there.com', None),
    2525    (validate_email, 'email@[127.0.0.1]', None),
     26    (validate_email, 'email@localhost', None),
    2627
    2728    (validate_email, None, ValidationError),
    2829    (validate_email, '', ValidationError),
Back to Top