From 6c9b9ad2690902a348a7f6ea7a5533efcd628c78 Mon Sep 17 00:00:00 2001 From: Jeff Ferland Date: Tue, 19 Mar 2013 15:54:11 -0700 Subject: [PATCH] Fix several issues with adding IP ranges * Prevents non-adjacent ranges from being added * Prevents creating invalid subnets * Fixes a bug where the integer value of an IPv6 address that is less than 32 bits would be treated as an IPv4 address during addition. --- ChangeLog | 6 ++++++ IPy.py | 13 +++++++++---- test/test_IPy.py | 6 ++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9d9cfa9..2782c7f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,12 @@ Version 0.80 * Drop support of Python older than 2.4 * Python 3 does not need 2to3 conversion anymore (same code base) +* Fix adding of non-adjacent networks + 192.168.0.0/24 + 192.168.255.0/24 made 192.168.0.0/23 +* Fix adding networks that don't create a valid subnet + 192.168.1.0/24 + 192.168.2.0/24 made 192.168.1.0/23 +* Fix adding with an IPv6 address where .int() was < 32 bits made IPy believe it + was an IPv4 address. Version 0.76 (2013-03-19) ------------------------- diff --git a/IPy.py b/IPy.py index e83f8d0..a0d4203 100644 --- a/IPy.py +++ b/IPy.py @@ -977,10 +977,15 @@ def __add__(self, other): if self > other: # fixed by Skinny Puppy return other.__add__(self) - else: - ret = IP(self.int()) - ret._prefixlen = self.prefixlen() - 1 - return ret + if other.int() - self[-1].int() != 1: + raise ValueError("Only adjacent networks can be added together.") + ret = IP(self.int(), ipversion=self._ipversion) + ret._prefixlen = self.prefixlen() - 1 + if not _checkNetaddrWorksWithPrefixlen(ret.ip, ret._prefixlen, + ret._ipversion): + raise ValueError("The resulting %s has invalid prefix length (%s)" + % (repr(ret), ret._prefixlen)) + return ret def get_mac(self): """ diff --git a/test/test_IPy.py b/test/test_IPy.py index c35b69f..60b722f 100644 --- a/test/test_IPy.py +++ b/test/test_IPy.py @@ -715,7 +715,12 @@ def testMisc(self): ip = IPy.IP('133.45.0/24') ip2 = IPy.IP('133.45.1/24') + ip3 = IPy.IP('133.45.2/24') self.assertEqual((ip + ip2).prefixlen(),23) + # Non-adjacent ranges + self.assertRaises(ValueError, IPy.IP.__add__, ip, ip3) + # Resulting invalid prefix + self.assertRaises(ValueError, IPy.IP.__add__, ip2, ip3) ip2 = IPy.IP('133.44.255.255'); #$T->ok_eqnum ($ip->bincomp('gt',$ip2),1,$ip->error()); @@ -756,6 +761,7 @@ def testMisc(self): ip = IPy.IP('::e000:0/112') ip2 = IPy.IP('::e001:0/112') self.assertEqual(ip.__add__(ip2).prefixlen(),111) + self.assertEqual(ip.__add__(ip2).version(),6) ip2 = IPy.IP('::dfff:ffff') #$T->ok_eqnum ($ip->bincomp('gt',$ip2),1,$ip->error());