1
0
mirror of https://github.com/django/django.git synced 2025-06-02 18:19:11 +00:00

[5.0.x] Fixed #36098 -- Fixed validate_ipv6_address()/validate_ipv46_address() crash for non-string values.

Regression in ca2be7724e1244a4cb723de40a070f873c6e94bf.

Backport of b3c5830769d8a5dbf2f974da7116fe503c9454d9 from main.
This commit is contained in:
Mariusz Felisiak 2025-01-14 23:08:50 +01:00 committed by Natalia
parent 61fed511f1
commit 21dfd30d69
6 changed files with 65 additions and 4 deletions

View File

@ -49,12 +49,14 @@ def clean_ipv6_address(
return str(addr) return str(addr)
def is_valid_ipv6_address(ip_str): def is_valid_ipv6_address(ip_addr):
""" """
Return whether or not the `ip_str` string is a valid IPv6 address. Return whether the `ip_addr` object is a valid IPv6 address.
""" """
if isinstance(ip_addr, ipaddress.IPv6Address):
return True
try: try:
_ipv6_address_from_str(ip_str) _ipv6_address_from_str(ip_addr)
except ValueError: except (TypeError, ValueError):
return False return False
return True return True

14
docs/releases/4.2.19.txt Normal file
View File

@ -0,0 +1,14 @@
===========================
Django 4.2.19 release notes
===========================
*Expected February 5, 2025*
Django 4.2.19 fixes a regression in 4.2.18.
Bugfixes
========
* Fixed a regression in Django 4.2.18 that caused ``validate_ipv6_address()``
and ``validate_ipv46_address()`` to crash when handling non-string values
(:ticket:`36098`).

14
docs/releases/5.0.12.txt Normal file
View File

@ -0,0 +1,14 @@
===========================
Django 5.0.12 release notes
===========================
*Expected February 5, 2025*
Django 5.0.12 fixes a regression in 5.0.11.
Bugfixes
========
* Fixed a regression in Django 5.0.11 that caused ``validate_ipv6_address()``
and ``validate_ipv46_address()`` to crash when handling non-string values
(:ticket:`36098`).

View File

@ -25,6 +25,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
5.0.12
5.0.11 5.0.11
5.0.10 5.0.10
5.0.9 5.0.9
@ -44,6 +45,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
4.2.19
4.2.18 4.2.18
4.2.17 4.2.17
4.2.16 4.2.16

View File

@ -1,5 +1,7 @@
import traceback import traceback
from decimal import Decimal
from io import StringIO from io import StringIO
from ipaddress import IPv6Address
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.test import SimpleTestCase from django.test import SimpleTestCase
@ -23,6 +25,16 @@ class TestUtilsIPv6(SimpleTestCase):
self.assertTrue(is_valid_ipv6_address("::ffff:254.42.16.14")) self.assertTrue(is_valid_ipv6_address("::ffff:254.42.16.14"))
self.assertTrue(is_valid_ipv6_address("::ffff:0a0a:0a0a")) self.assertTrue(is_valid_ipv6_address("::ffff:0a0a:0a0a"))
def test_validates_correct_with_ipv6_instance(self):
cases = [
IPv6Address("::ffff:2.125.160.216"),
IPv6Address("fe80::1"),
IPv6Address("::"),
]
for case in cases:
with self.subTest(case=case):
self.assertIs(is_valid_ipv6_address(case), True)
def test_validates_incorrect_plain_address(self): def test_validates_incorrect_plain_address(self):
self.assertFalse(is_valid_ipv6_address("foo")) self.assertFalse(is_valid_ipv6_address("foo"))
self.assertFalse(is_valid_ipv6_address("127.0.0.1")) self.assertFalse(is_valid_ipv6_address("127.0.0.1"))
@ -45,6 +57,12 @@ class TestUtilsIPv6(SimpleTestCase):
self.assertFalse(is_valid_ipv6_address("::999.42.16.14")) self.assertFalse(is_valid_ipv6_address("::999.42.16.14"))
self.assertFalse(is_valid_ipv6_address("::zzzz:0a0a")) self.assertFalse(is_valid_ipv6_address("::zzzz:0a0a"))
def test_validates_incorrect_with_non_string(self):
cases = [None, [], {}, (), Decimal("2.46"), 192.168, 42]
for case in cases:
with self.subTest(case=case):
self.assertIs(is_valid_ipv6_address(case), False)
def test_cleans_plain_address(self): def test_cleans_plain_address(self):
self.assertEqual(clean_ipv6_address("DEAD::0:BEEF"), "dead::beef") self.assertEqual(clean_ipv6_address("DEAD::0:BEEF"), "dead::beef")
self.assertEqual( self.assertEqual(

View File

@ -1,3 +1,4 @@
import ipaddress
import re import re
import types import types
from datetime import datetime, timedelta from datetime import datetime, timedelta
@ -381,15 +382,25 @@ TEST_DATA = [
(validate_ipv6_address, "fe80::1", None), (validate_ipv6_address, "fe80::1", None),
(validate_ipv6_address, "::1", None), (validate_ipv6_address, "::1", None),
(validate_ipv6_address, "1:2:3:4:5:6:7:8", None), (validate_ipv6_address, "1:2:3:4:5:6:7:8", None),
(validate_ipv6_address, ipaddress.IPv6Address("::ffff:2.125.160.216"), None),
(validate_ipv6_address, ipaddress.IPv6Address("fe80::1"), None),
(validate_ipv6_address, Decimal("33.1"), ValidationError),
(validate_ipv6_address, 9.22, ValidationError),
(validate_ipv6_address, "1:2", ValidationError), (validate_ipv6_address, "1:2", ValidationError),
(validate_ipv6_address, "::zzz", ValidationError), (validate_ipv6_address, "::zzz", ValidationError),
(validate_ipv6_address, "12345::", ValidationError), (validate_ipv6_address, "12345::", ValidationError),
(validate_ipv46_address, "1.1.1.1", None), (validate_ipv46_address, "1.1.1.1", None),
(validate_ipv46_address, "255.0.0.0", None), (validate_ipv46_address, "255.0.0.0", None),
(validate_ipv46_address, "0.0.0.0", None), (validate_ipv46_address, "0.0.0.0", None),
(validate_ipv46_address, ipaddress.IPv4Address("1.1.1.1"), None),
(validate_ipv46_address, ipaddress.IPv4Address("255.0.0.0"), None),
(validate_ipv46_address, "fe80::1", None), (validate_ipv46_address, "fe80::1", None),
(validate_ipv46_address, "::1", None), (validate_ipv46_address, "::1", None),
(validate_ipv46_address, "1:2:3:4:5:6:7:8", None), (validate_ipv46_address, "1:2:3:4:5:6:7:8", None),
(validate_ipv46_address, ipaddress.IPv6Address("::ffff:2.125.160.216"), None),
(validate_ipv46_address, ipaddress.IPv6Address("fe80::1"), None),
(validate_ipv46_address, Decimal("33.1"), ValidationError),
(validate_ipv46_address, 9.22, ValidationError),
(validate_ipv46_address, "256.1.1.1", ValidationError), (validate_ipv46_address, "256.1.1.1", ValidationError),
(validate_ipv46_address, "25.1.1.", ValidationError), (validate_ipv46_address, "25.1.1.", ValidationError),
(validate_ipv46_address, "25,1,1,1", ValidationError), (validate_ipv46_address, "25,1,1,1", ValidationError),