From 2a66d12e77821fbd4f2e4c3cb93eb9f84ca6f9ab Mon Sep 17 00:00:00 2001
From: Erik Romijn <eromijn@solidlinks.nl>
Date: Fri, 16 May 2014 15:13:11 +0200
Subject: [PATCH] [1.7.x] Fixed #22579 -- Corrected validation for email to
 reject trailing slash

Backport of 424fe76349a2e34eafef13c2450a7a1f4d3115a6 from master.
---
 django/core/validators.py | 4 ++--
 tests/validators/tests.py | 2 ++
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/django/core/validators.py b/django/core/validators.py
index da59c0e924..1e599ec765 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -68,7 +68,7 @@ class RegexValidator(object):
 class URLValidator(RegexValidator):
     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'(?:(?:[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
@@ -124,7 +124,7 @@ class EmailValidator(object):
         r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"$)',  # quoted-string
         re.IGNORECASE)
     domain_regex = re.compile(
-        r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,})$',
+        r'(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}|[A-Z0-9-]{2,}(?<!-))$',
         re.IGNORECASE)
     literal_regex = re.compile(
         # literal form, ipv4 or ipv6 address (SMTP 4.1.3)
diff --git a/tests/validators/tests.py b/tests/validators/tests.py
index d073bf264f..f586270040 100644
--- a/tests/validators/tests.py
+++ b/tests/validators/tests.py
@@ -58,6 +58,7 @@ TEST_DATA = (
     (validate_email, 'email@[::ffff:127.0.0.256]', ValidationError),
     (validate_email, 'example@invalid-.com', ValidationError),
     (validate_email, 'example@-invalid.com', ValidationError),
+    (validate_email, 'example@invalid.com-', ValidationError),
     (validate_email, 'example@inv-.alid-.com', ValidationError),
     (validate_email, 'example@inv-.-alid.com', ValidationError),
     (validate_email, 'test@example.com\n\n<script src="x.js">', ValidationError),
@@ -174,6 +175,7 @@ TEST_DATA = (
     (URLValidator(), 'http://.com', ValidationError),
     (URLValidator(), 'http://invalid-.com', ValidationError),
     (URLValidator(), 'http://-invalid.com', ValidationError),
+    (URLValidator(), 'http://invalid.com-', ValidationError),
     (URLValidator(), 'http://inv-.alid-.com', ValidationError),
     (URLValidator(), 'http://inv-.-alid.com', ValidationError),
     (URLValidator(), 'file://localhost/path', ValidationError),