Skip to content

Commit 043dfad

Browse files
felixxmnessita
authored andcommitted
[4.2.x] Fixed #36098 -- Fixed validate_ipv6_address()/validate_ipv46_address() crash for non-string values.
Regression in ca2be77. Backport of b3c5830 from main.
1 parent 8769b44 commit 043dfad

File tree

5 files changed

+50
-4
lines changed

5 files changed

+50
-4
lines changed

django/utils/ipv6.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@ def clean_ipv6_address(
4949
return str(addr)
5050

5151

52-
def is_valid_ipv6_address(ip_str):
52+
def is_valid_ipv6_address(ip_addr):
5353
"""
54-
Return whether or not the `ip_str` string is a valid IPv6 address.
54+
Return whether the `ip_addr` object is a valid IPv6 address.
5555
"""
56+
if isinstance(ip_addr, ipaddress.IPv6Address):
57+
return True
5658
try:
57-
_ipv6_address_from_str(ip_str)
58-
except ValueError:
59+
_ipv6_address_from_str(ip_addr)
60+
except (TypeError, ValueError):
5961
return False
6062
return True

docs/releases/4.2.19.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
===========================
2+
Django 4.2.19 release notes
3+
===========================
4+
5+
*Expected February 5, 2025*
6+
7+
Django 4.2.19 fixes a regression in 4.2.18.
8+
9+
Bugfixes
10+
========
11+
12+
* Fixed a regression in Django 4.2.18 that caused ``validate_ipv6_address()``
13+
and ``validate_ipv46_address()`` to crash when handling non-string values
14+
(:ticket:`36098`).

docs/releases/index.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ versions of the documentation contain the release notes for any later releases.
2626
.. toctree::
2727
:maxdepth: 1
2828

29+
4.2.19
2930
4.2.18
3031
4.2.17
3132
4.2.16

tests/utils_tests/test_ipv6.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import traceback
2+
from decimal import Decimal
23
from io import StringIO
4+
from ipaddress import IPv6Address
35

46
from django.core.exceptions import ValidationError
57
from django.test import SimpleTestCase
@@ -24,6 +26,16 @@ def test_validates_correct_with_v4mapping(self):
2426
self.assertTrue(is_valid_ipv6_address("::ffff:254.42.16.14"))
2527
self.assertTrue(is_valid_ipv6_address("::ffff:0a0a:0a0a"))
2628

29+
def test_validates_correct_with_ipv6_instance(self):
30+
cases = [
31+
IPv6Address("::ffff:2.125.160.216"),
32+
IPv6Address("fe80::1"),
33+
IPv6Address("::"),
34+
]
35+
for case in cases:
36+
with self.subTest(case=case):
37+
self.assertIs(is_valid_ipv6_address(case), True)
38+
2739
def test_validates_incorrect_plain_address(self):
2840
self.assertFalse(is_valid_ipv6_address("foo"))
2941
self.assertFalse(is_valid_ipv6_address("127.0.0.1"))
@@ -46,6 +58,12 @@ def test_validates_incorrect_with_v4mapping(self):
4658
self.assertFalse(is_valid_ipv6_address("::999.42.16.14"))
4759
self.assertFalse(is_valid_ipv6_address("::zzzz:0a0a"))
4860

61+
def test_validates_incorrect_with_non_string(self):
62+
cases = [None, [], {}, (), Decimal("2.46"), 192.168, 42]
63+
for case in cases:
64+
with self.subTest(case=case):
65+
self.assertIs(is_valid_ipv6_address(case), False)
66+
4967
def test_cleans_plain_address(self):
5068
self.assertEqual(clean_ipv6_address("DEAD::0:BEEF"), "dead::beef")
5169
self.assertEqual(

tests/validators/tests.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ipaddress
12
import re
23
import types
34
from datetime import datetime, timedelta
@@ -381,15 +382,25 @@
381382
(validate_ipv6_address, "fe80::1", None),
382383
(validate_ipv6_address, "::1", None),
383384
(validate_ipv6_address, "1:2:3:4:5:6:7:8", None),
385+
(validate_ipv6_address, ipaddress.IPv6Address("::ffff:2.125.160.216"), None),
386+
(validate_ipv6_address, ipaddress.IPv6Address("fe80::1"), None),
387+
(validate_ipv6_address, Decimal("33.1"), ValidationError),
388+
(validate_ipv6_address, 9.22, ValidationError),
384389
(validate_ipv6_address, "1:2", ValidationError),
385390
(validate_ipv6_address, "::zzz", ValidationError),
386391
(validate_ipv6_address, "12345::", ValidationError),
387392
(validate_ipv46_address, "1.1.1.1", None),
388393
(validate_ipv46_address, "255.0.0.0", None),
389394
(validate_ipv46_address, "0.0.0.0", None),
395+
(validate_ipv46_address, ipaddress.IPv4Address("1.1.1.1"), None),
396+
(validate_ipv46_address, ipaddress.IPv4Address("255.0.0.0"), None),
390397
(validate_ipv46_address, "fe80::1", None),
391398
(validate_ipv46_address, "::1", None),
392399
(validate_ipv46_address, "1:2:3:4:5:6:7:8", None),
400+
(validate_ipv46_address, ipaddress.IPv6Address("::ffff:2.125.160.216"), None),
401+
(validate_ipv46_address, ipaddress.IPv6Address("fe80::1"), None),
402+
(validate_ipv46_address, Decimal("33.1"), ValidationError),
403+
(validate_ipv46_address, 9.22, ValidationError),
393404
(validate_ipv46_address, "256.1.1.1", ValidationError),
394405
(validate_ipv46_address, "25.1.1.", ValidationError),
395406
(validate_ipv46_address, "25,1,1,1", ValidationError),

0 commit comments

Comments
 (0)