Commit 68f216a6 authored by Jannis Leidel's avatar Jannis Leidel
Browse files

Fixed #12989 - Fixed verification of IDN URLs. Thanks to Fraser Nevett for the report and patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12620 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent d7abb33e
Loading
Loading
Loading
Loading
+7 −12
Original line number Diff line number Diff line
@@ -58,23 +58,18 @@ class URLValidator(RegexValidator):
        except ValidationError, e:
            # Trivial case failed. Try for possible IDN domain
            if value:
                original = value
                value = smart_unicode(value)
                splitted = urlparse.urlsplit(value)
                scheme, netloc, path, query, fragment = urlparse.urlsplit(value)
                try:
                    netloc_ace = splitted[1].encode('idna') # IDN -> ACE
                    netloc = netloc.encode('idna') # IDN -> ACE
                except UnicodeError: # invalid domain part
                    raise e
                value = value.replace(splitted[1], netloc_ace)
                # If no URL path given, assume /
                if not splitted[2]:
                    value += u'/'
                super(URLValidator, self).__call__(value)
                # After validation revert ACE encoded domain-part to
                # original (IDN) value as suggested by RFC 3490
                value = original
                url = urlparse.urlunsplit((scheme, netloc, path, query, fragment))
                super(URLValidator, self).__call__(url)
            else:
                raise
        else:
            url = value

        if self.verify_exists:
            import urllib2
@@ -86,7 +81,7 @@ class URLValidator(RegexValidator):
                "User-Agent": self.user_agent,
            }
            try:
                req = urllib2.Request(value, None, headers)
                req = urllib2.Request(url, None, headers)
                u = urllib2.urlopen(req)
            except ValueError:
                raise ValidationError(_(u'Enter a valid URL.'), code='invalid')
+7 −0
Original line number Diff line number Diff line
@@ -531,6 +531,13 @@ class FieldsTests(TestCase):
            f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page
        except ValidationError, e:
            self.assertEqual("[u'This URL appears to be a broken link.']", str(e))
        # Valid and existent IDN
        self.assertEqual(u'http://\u05e2\u05d1\u05e8\u05d9\u05ea.idn.icann.org/', f.clean(u'http://עברית.idn.icann.org/'))
        # Valid but non-existent IDN
        try:
            f.clean(u'http://broken.עברית.idn.icann.org/')
        except ValidationError, e:
            self.assertEqual("[u'This URL appears to be a broken link.']", str(e))

    def test_urlfield_40(self):
        f = URLField(verify_exists=True, required=False)