gh-117566: fix IPv6Address.is_loopback for IPv4-mapped loopbacks (GH-117567)

While properties like IPv6Address.is_private account for IPv4-mapped
IPv6 addresses, such as for example:

    >>> ipaddress.ip_address("192.168.0.1").is_private
    True
    >>> ipaddress.ip_address("::ffff:192.168.0.1").is_private
    True
...the same doesn't currently apply to the is_loopback property:
    >>> ipaddress.ip_address("127.0.0.1").is_loopback
    True
    >>> ipaddress.ip_address("::ffff:127.0.0.1").is_loopback
    False

At minimum, this inconsistency between different properties is
counter-intuitive. Moreover, ::ffff:127.0.0.0/104 is for all intents and
purposes a loopback address, and should be treated as such.
This commit is contained in:
Faidon Liambotis 2024-04-25 18:17:40 +03:00 committed by GitHub
parent eb20a7d12c
commit fb7f79b4da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 1 deletions

View file

@ -2446,6 +2446,22 @@ class IpaddrUnitTest(unittest.TestCase):
self.assertEqual(
False, ipaddress.ip_address('::ffff:172.32.0.0').is_private)
def testIpv4MappedLoopbackCheck(self):
# test networks
self.assertEqual(True, ipaddress.ip_network(
'::ffff:127.100.200.254/128').is_loopback)
self.assertEqual(True, ipaddress.ip_network(
'::ffff:127.42.0.0/112').is_loopback)
self.assertEqual(False, ipaddress.ip_network(
'::ffff:128.0.0.0').is_loopback)
# test addresses
self.assertEqual(True, ipaddress.ip_address(
'::ffff:127.100.200.254').is_loopback)
self.assertEqual(True, ipaddress.ip_address(
'::ffff:127.42.0.0').is_loopback)
self.assertEqual(False, ipaddress.ip_address(
'::ffff:128.0.0.0').is_loopback)
def testAddrExclude(self):
addr1 = ipaddress.ip_network('10.1.1.0/24')
addr2 = ipaddress.ip_network('10.1.1.0/26')