Skip to content

Instantly share code, notes, and snippets.

@loic
Created December 2, 2014 18:55
Show Gist options
  • Save loic/386830e46e8d2aca9dcb to your computer and use it in GitHub Desktop.
Save loic/386830e46e8d2aca9dcb to your computer and use it in GitHub Desktop.
diff --git a/django/core/validators.py b/django/core/validators.py
index e0fd995..236822b 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -66,14 +66,20 @@ class RegexValidator(object):
@deconstructible
class URLValidator(RegexValidator):
+ ul = '\u00a1-\uffff' # unicode letters range (must be a unicode string, not a raw string)
+
+ ipv4_pattern = r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
+ ipv6_pattern = r'\[[0-9a-f:\.]+\]' # (simple regex, validated later)
+ host_pattern = r'(?:[a-z0-9{ul}](?:[a-z0-9{ul}\-]*[a-z0-9{ul}])?\.?)+'.format(ul=ul)
+
regex = re.compile(
r'^(?:[a-z0-9\.\-]*)://' # scheme is validated separately
- r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}(?<!-)\.?)|' # domain...
- r'localhost|' # localhost...
- r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|' # ...or ipv4
- r'\[?[A-F0-9]*:[A-F0-9:]+\]?)' # ...or ipv6
- r'(?::\d+)?' # optional port
- r'(?:/?|[/?]\S+)$', re.IGNORECASE)
+ r'(?:\S+(?::\S*)?@)?' # user:pass authentication
+ r'(?:' + ipv4_pattern + '|' + ipv6_pattern + '|' + host_pattern + ')'
+ r'(?::\d{2,5})?' # port
+ r'(?:[/?#][^\s]*)?' # resource path
+ r'$', re.IGNORECASE)
+
message = _('Enter a valid URL.')
schemes = ['http', 'https', 'ftp', 'ftps']
diff --git a/tests/validators/invalid_urls.txt b/tests/validators/invalid_urls.txt
index 37c3477..5f6b22c 100644
--- a/tests/validators/invalid_urls.txt
+++ b/tests/validators/invalid_urls.txt
@@ -1,7 +1,5 @@
foo
http://
-http://example
-http://example.
http://.com
http://invalid-.com
http://-invalid.com
@@ -10,3 +8,35 @@ http://inv-.alid-.com
http://inv-.-alid.com
file://localhost/path
git://example.com/
+http://.
+http://..
+http://../
+http://?
+http://??
+http://??/
+http://#
+http://##
+http://##/
+http://foo.bar?q=Spaces should be encoded
+//
+//a
+///a
+///
+http:///a
+foo.com
+rdar://1234
+h://test
+http:// shouldfail.com
+:// should fail
+http://foo.bar/foo(bar)baz quux
+http://-error-.invalid/
+http://-a.b.co
+http://a.b-.co
+http:/
+http://
+http://
+http://.www.foo.bar/
+http://.www.foo.bar./
+http://[::1:2::3]:8080/
+http://[]
+http://[]:8080
diff --git a/tests/validators/valid_urls.txt b/tests/validators/valid_urls.txt
index 9f1519c..0d1dd77 100644
--- a/tests/validators/valid_urls.txt
+++ b/tests/validators/valid_urls.txt
@@ -2,6 +2,7 @@ http://www.djangoproject.com/
HTTP://WWW.DJANGOPROJECT.COM/
http://localhost/
http://example.com/
+http://example.com./
http://www.example.com/
http://www.example.com:8000/test
http://valid-with-hyphens.com/
@@ -14,3 +15,49 @@ http://example.com/index.php?something=value&another=value2
https://example.com/
ftp://example.com/
ftps://example.com/
+http://foo.com/blah_blah
+http://foo.com/blah_blah/
+http://foo.com/blah_blah_(wikipedia)
+http://foo.com/blah_blah_(wikipedia)_(again)
+http://www.example.com/wpstyle/?p=364
+https://www.example.com/foo/?bar=baz&inga=42&quux
+http://✪df.ws/123
+http://userid:[email protected]:8080
+http://userid:[email protected]:8080/
+http://[email protected]
+http://[email protected]/
+http://[email protected]:8080
+http://[email protected]:8080/
+http://userid:[email protected]
+http://userid:[email protected]/
+http://142.42.1.1/
+http://142.42.1.1:8080/
+http://➡.ws/䨹
+http://⌘.ws
+http://⌘.ws/
+http://foo.com/blah_(wikipedia)#cite-1
+http://foo.com/blah_(wikipedia)_blah#cite-1
+http://foo.com/unicode_(✪)_in_parens
+http://foo.com/(something)?after=parens
+http://☺.damowmow.com/
+http://code.google.com/events/#&product=browser
+http://j.mp
+ftp://foo.bar/baz
+http://foo.bar/?q=Test%20URL-encoded%20stuff
+http://مثال.إختبار
+http://例子.测试
+http://उदाहरण.परीक्षा
+http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com
+http://1337.net
+http://a.b-c.de
+http://223.255.255.254
+ftps://foo.bar/
+http://10.1.1.254
+http://[FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80/index.html
+http://[::192.9.5.5]/ipng
+http://[::ffff:192.9.5.5]/ipng
+http://[::1]:8080/
+http://0.0.0.0/
+http://255.255.255.255
+http://224.0.0.0
+http://224.1.1.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment