From 93024e734d7432843ae155876dddb6b8f283c868 Mon Sep 17 00:00:00 2001 From: Nandika Gupta Date: Tue, 6 Oct 2026 19:03:46 +0000 Subject: [PATCH] fix: IP() refuses integers out of range --- debian/changelog | 9 +++++++++ ipaddr.py | 5 ++++- tests/test_ipaddr.py | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 1cfaec4..cfa89f2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,12 @@ +confconsole (2.2.3+keel16) trixie; urgency=low + + * ipaddr.IP() refuses an integer outside 0 to 2**32-1 with + Error("ip out of range"). Before, IP(2**32) or IP(-1) was created and + only failed later in str() with a struct.error. IPRange computes its + broadcast address the same as before. + + -- Nandika Gupta Tue, 06 Oct 2026 19:00:00 +0000 + confconsole (2.2.3+keel15) trixie; urgency=low * The Overlay network screen keeps one place in the Instance menu. It diff --git a/ipaddr.py b/ipaddr.py index 4999015..70bcf8a 100644 --- a/ipaddr.py +++ b/ipaddr.py @@ -48,6 +48,9 @@ def __new__(cls: Type["IP"], arg: AnyIP) -> "IP": return int.__new__(cls, int(arg)) elif isinstance(arg, int): + if not 0 <= arg <= 0xFFFFFFFF: + raise Error(f"ip out of range ({arg})") + return int.__new__(cls, arg) else: @@ -89,7 +92,7 @@ def __init__(self, ip: AnyIP, netmask: AnyIP): self.ip = IP(ip) self.netmask = IP(netmask) self.network = self.ip & self.netmask - self.broadcast = self.network + 2**32 - self.netmask - 1 + self.broadcast = IP(int(self.network) + 2**32 - int(self.netmask) - 1) self.cidr = int(32 - math.log(2**32 - self.netmask, 2)) def __contains__(self, ip: AnyIP) -> bool: diff --git a/tests/test_ipaddr.py b/tests/test_ipaddr.py index a397331..d93ad03 100644 --- a/tests/test_ipaddr.py +++ b/tests/test_ipaddr.py @@ -63,6 +63,19 @@ def test_illegal_string_raises_error(self): with pytest.raises(ipaddr.Error, match="illegal ip"): IP("300.0.2.1") + @pytest.mark.parametrize("value", [0, 0xFFFFFFFF]) + def test_int_at_the_ends_of_the_range(self, value): + assert int(IP(value)) == value + + @pytest.mark.parametrize("value", [-1, 2**32]) + def test_int_out_of_range_raises_error(self, value): + with pytest.raises(ipaddr.Error, match="ip out of range"): + IP(value) + + def test_operator_past_the_last_address_raises_error(self): + with pytest.raises(ipaddr.Error, match="ip out of range"): + IP("255.255.255.255") + 1 + @pytest.mark.parametrize( "op, operand, expected", [