From 4154d1ffd938ba3b6e464011c74dd40cc0497b77 Mon Sep 17 00:00:00 2001 From: SimonIT Date: Tue, 15 Feb 2022 22:48:31 +0100 Subject: [PATCH] Improve IPv6 validation fixes #107 --- tests/test_ipv6.py | 13 ++++++++++++- validators/ip_address.py | 12 +++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/tests/test_ipv6.py b/tests/test_ipv6.py index 3f321404..70326470 100644 --- a/tests/test_ipv6.py +++ b/tests/test_ipv6.py @@ -5,8 +5,10 @@ @pytest.mark.parametrize(('address',), [ + ('::',), ('::1',), - ('dead:beef:0:0:0:0:42:1',), + ('1::',), + ('dead:beef:0:0:0:0000:42:1',), ('abcd:ef::42:1',), ('0:0:0:0:0:ffff:1.2.3.4',), ('::192.168.30.2',), @@ -21,6 +23,15 @@ def test_returns_true_on_valid_ipv6_address(address): ('abcd:1234::123::1',), ('1:2:3:4:5:6:7:8:9',), ('abcd::1ffff',), + ('1111:',), + (':8888',), + (':1.2.3.4',), + ('18:05',), + (':',), + (':1:2:',), + (':1:2::',), + ('::1:2::',), + ('8::1:2::9',), ]) def test_returns_failed_validation_on_invalid_ipv6_address(address): assert isinstance(ipv6(address), ValidationFailure) diff --git a/validators/ip_address.py b/validators/ip_address.py index ba36cdc6..c3b26f36 100644 --- a/validators/ip_address.py +++ b/validators/ip_address.py @@ -1,3 +1,5 @@ +from operator import xor + from .utils import validator @@ -57,7 +59,7 @@ def ipv4_cidr(value): @validator def ipv6(value): """ - Return whether or not given value is a valid IP version 6 address + Return whether a given value is a valid IP version 6 address (including IPv4-mapped IPv6 addresses). This validator is based on `WTForms IPAddress validator`_. @@ -112,9 +114,13 @@ def ipv6(value): if not 0 <= num <= 65536: return False - if count_blank < 2: + if count_blank == 0 and len(ipv6_groups) == max_groups: + return True + elif count_blank == 1 and ipv6_groups[-1] and ipv6_groups[0]: + return True + elif count_blank == 2 and ((ipv6_groups[0] and not ipv6_groups[-1]) or (not ipv6_groups[0] and ipv6_groups[-1])): return True - elif count_blank == 2 and not ipv6_groups[0] and not ipv6_groups[1]: + elif count_blank == 3 and len(ipv6_groups) == 3: return True return False