commit:     d79dcfb326c7ad52927fdb926a6f0ebd776bf196
Author:     Michał Górny <mgorny <AT> gentoo <DOT> org>
AuthorDate: Tue Jul  4 02:40:23 2023 +0000
Commit:     Michał Górny <mgorny <AT> gentoo <DOT> org>
CommitDate: Tue Jul  4 02:40:23 2023 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=d79dcfb3

dev-python/django: Backport one more py3.11 fix to 3.2.20

Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>

 dev-python/django/django-3.2.20.ebuild             |   2 +
 .../django/files/django-3.2.20-urlsplit.patch      | 111 +++++++++++++++++++++
 2 files changed, 113 insertions(+)

diff --git a/dev-python/django/django-3.2.20.ebuild 
b/dev-python/django/django-3.2.20.ebuild
index 60bea073329b..ca46ed4c7d3b 100644
--- a/dev-python/django/django-3.2.20.ebuild
+++ b/dev-python/django/django-3.2.20.ebuild
@@ -55,6 +55,8 @@ BDEPEND="
 PATCHES=(
        "${FILESDIR}"/${PN}-3.1-bashcomp.patch
        "${FILESDIR}"/django-3.2.19-py311.patch
+       # needed for Python 3.11
+       "${FILESDIR}"/django-3.2.20-urlsplit.patch
 )
 
 distutils_enable_sphinx docs --no-autodoc

diff --git a/dev-python/django/files/django-3.2.20-urlsplit.patch 
b/dev-python/django/files/django-3.2.20-urlsplit.patch
new file mode 100644
index 000000000000..4883da38c0f5
--- /dev/null
+++ b/dev-python/django/files/django-3.2.20-urlsplit.patch
@@ -0,0 +1,111 @@
+From 74fee3f5cab1481dcb299b6eeaf82f862470bafa Mon Sep 17 00:00:00 2001
+From: mendespedro <[email protected]>
+Date: Wed, 15 Dec 2021 11:55:19 -0300
+Subject: [PATCH] Fixed #33367 -- Fixed URLValidator crash in some edge cases.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+[backported to 3.2.x by Michał Górny]
+---
+ django/core/validators.py                     | 13 +++---
+ .../forms_tests/field_tests/test_urlfield.py  | 40 +++++++++++++++----
+ 2 files changed, 40 insertions(+), 13 deletions(-)
+
+diff --git a/django/core/validators.py b/django/core/validators.py
+index b9b58dfa61..aad21f95ea 100644
+--- a/django/core/validators.py
++++ b/django/core/validators.py
+@@ -111,15 +111,16 @@ class URLValidator(RegexValidator):
+             raise ValidationError(self.message, code=self.code, 
params={'value': value})
+ 
+         # Then check full URL
++        try:
++            splitted_url = urlsplit(value)
++        except ValueError:
++            raise ValidationError(self.message, code=self.code, 
params={'value': value})
+         try:
+             super().__call__(value)
+         except ValidationError as e:
+             # Trivial case failed. Try for possible IDN domain
+             if value:
+-                try:
+-                    scheme, netloc, path, query, fragment = urlsplit(value)
+-                except ValueError:  # for example, "Invalid IPv6 URL"
+-                    raise ValidationError(self.message, code=self.code, 
params={'value': value})
++                scheme, netloc, path, query, fragment = splitted_url
+                 try:
+                     netloc = punycode(netloc)  # IDN -> ACE
+                 except UnicodeError:  # invalid domain part
+@@ -130,7 +131,7 @@ class URLValidator(RegexValidator):
+                 raise
+         else:
+             # Now verify IPv6 in the netloc part
+-            host_match = re.search(r'^\[(.+)\](?::\d{2,5})?$', 
urlsplit(value).netloc)
++            host_match = re.search(r'^\[(.+)\](?::\d{1,5})?$', 
splitted_url.netloc)
+             if host_match:
+                 potential_ip = host_match[1]
+                 try:
+@@ -142,7 +143,7 @@ class URLValidator(RegexValidator):
+         # section 3.1. It's defined to be 255 bytes or less, but this includes
+         # one byte for the length of the name and one byte for the trailing 
dot
+         # that's used to indicate absolute names in DNS.
+-        if len(urlsplit(value).hostname) > 253:
++        if splitted_url.hostname is None or len(splitted_url.hostname) > 253:
+             raise ValidationError(self.message, code=self.code, 
params={'value': value})
+ 
+ 
+diff --git a/tests/forms_tests/field_tests/test_urlfield.py 
b/tests/forms_tests/field_tests/test_urlfield.py
+index 19e4351c6a..68b148e7b7 100644
+--- a/tests/forms_tests/field_tests/test_urlfield.py
++++ b/tests/forms_tests/field_tests/test_urlfield.py
+@@ -135,13 +135,39 @@ class URLFieldTest(FormFieldAssertionsMixin, 
SimpleTestCase):
+     def test_urlfield_10(self):
+         """URLField correctly validates IPv6 (#18779)."""
+         f = URLField()
+-        urls = (
+-            'http://[12:34::3a53]/',
+-            'http://[a34:9238::]:8080/',
+-        )
+-        for url in urls:
+-            with self.subTest(url=url):
+-                self.assertEqual(url, f.clean(url))
++        tests = [
++            'foo',
++            'com.',
++            '.',
++            'http://',
++            'http://example',
++            'http://example.',
++            'http://.com',
++            'http://invalid-.com',
++            'http://-invalid.com',
++            'http://inv-.alid-.com',
++            'http://inv-.-alid.com',
++            '[a',
++            'http://[a',
++            # Non-string.
++            23,
++            # Hangs "forever" before fixing a catastrophic backtracking,
++            # see #11198.
++            'http://%s' % ('X' * 60,),
++            # A second example, to make sure the problem is really addressed,
++            # even on domains that don't fail the domain label length check in
++            # the regex.
++            'http://%s' % ("X" * 200,),
++            # urlsplit() raises ValueError.
++            '////]@N.AN',
++            # Empty hostname.
++            '#@A.bO',
++        ]
++        msg = "'Enter a valid URL.'"
++        for value in tests:
++            with self.subTest(value=value):
++                with self.assertRaisesMessage(ValidationError, msg):
++                    f.clean(value)
+ 
+     def test_urlfield_not_string(self):
+         f = URLField(required=False)
+-- 
+2.41.0
+

Reply via email to