Skip to content

Commit

Permalink
[4.2.x] Fixed #36098 -- Fixed validate_ipv6_address()/validate_ipv46_…
Browse files Browse the repository at this point in the history
…address() crash for non-string values.

Regression in ca2be77.

Backport of b3c5830 from main.
  • Loading branch information
felixxm authored and nessita committed Jan 15, 2025
1 parent 8769b44 commit 043dfad
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 4 deletions.
10 changes: 6 additions & 4 deletions django/utils/ipv6.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,14 @@ def clean_ipv6_address(
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:
_ipv6_address_from_str(ip_str)
except ValueError:
_ipv6_address_from_str(ip_addr)
except (TypeError, ValueError):
return False
return True
14 changes: 14 additions & 0 deletions docs/releases/4.2.19.txt
Original file line number Diff line number Diff line change
@@ -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`).
1 change: 1 addition & 0 deletions docs/releases/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1

4.2.19
4.2.18
4.2.17
4.2.16
Expand Down
18 changes: 18 additions & 0 deletions tests/utils_tests/test_ipv6.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import traceback
from decimal import Decimal
from io import StringIO
from ipaddress import IPv6Address

from django.core.exceptions import ValidationError
from django.test import SimpleTestCase
Expand All @@ -24,6 +26,16 @@ def test_validates_correct_with_v4mapping(self):
self.assertTrue(is_valid_ipv6_address("::ffff:254.42.16.14"))
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):
self.assertFalse(is_valid_ipv6_address("foo"))
self.assertFalse(is_valid_ipv6_address("127.0.0.1"))
Expand All @@ -46,6 +58,12 @@ def test_validates_incorrect_with_v4mapping(self):
self.assertFalse(is_valid_ipv6_address("::999.42.16.14"))
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):
self.assertEqual(clean_ipv6_address("DEAD::0:BEEF"), "dead::beef")
self.assertEqual(
Expand Down
11 changes: 11 additions & 0 deletions tests/validators/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ipaddress
import re
import types
from datetime import datetime, timedelta
Expand Down Expand Up @@ -381,15 +382,25 @@
(validate_ipv6_address, "fe80::1", None),
(validate_ipv6_address, "::1", 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, "::zzz", ValidationError),
(validate_ipv6_address, "12345::", ValidationError),
(validate_ipv46_address, "1.1.1.1", None),
(validate_ipv46_address, "255.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, "::1", 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, "25.1.1.", ValidationError),
(validate_ipv46_address, "25,1,1,1", ValidationError),
Expand Down

0 comments on commit 043dfad

Please sign in to comment.