Skip to content

Commit

Permalink
pythongh-123409: fix IPv6Address.reverse_pointer for IPv4-mapped ad…
Browse files Browse the repository at this point in the history
…dresses (pythonGH-123419)

Fix functionality that was broken with better textual representation for IPv4-mapped addresses (pythongh-87799)
(cherry picked from commit 77a2fb4)

Co-authored-by: Bénédikt Tran <[email protected]>
  • Loading branch information
picnixz authored and miss-islington committed Sep 2, 2024
1 parent 494181e commit d3f2b53
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 12 deletions.
21 changes: 15 additions & 6 deletions Lib/ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -1970,12 +1970,21 @@ def __init__(self, address):
def _explode_shorthand_ip_string(self):
ipv4_mapped = self.ipv4_mapped
if ipv4_mapped is None:
long_form = super()._explode_shorthand_ip_string()
else:
prefix_len = 30
raw_exploded_str = super()._explode_shorthand_ip_string()
long_form = "%s%s" % (raw_exploded_str[:prefix_len], str(ipv4_mapped))
return long_form
return super()._explode_shorthand_ip_string()
prefix_len = 30
raw_exploded_str = super()._explode_shorthand_ip_string()
return f"{raw_exploded_str[:prefix_len]}{ipv4_mapped!s}"

def _reverse_pointer(self):
ipv4_mapped = self.ipv4_mapped
if ipv4_mapped is None:
return super()._reverse_pointer()
prefix_len = 30
raw_exploded_str = super()._explode_shorthand_ip_string()[:prefix_len]
# ipv4 encoded using hexadecimal nibbles instead of decimals
ipv4_int = ipv4_mapped._ip
reverse_chars = f"{raw_exploded_str}{ipv4_int:008x}"[::-1].replace(':', '')
return '.'.join(reverse_chars) + '.ip6.arpa'

def _ipv4_mapped_ipv6_to_str(self):
"""Return convenient text representation of IPv4-mapped IPv6 address
Expand Down
42 changes: 36 additions & 6 deletions Lib/test/test_ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -2585,12 +2585,42 @@ def testExplodeShortHandIpStr(self):
self.assertEqual('192.168.178.1', addr4.exploded)

def testReversePointer(self):
addr1 = ipaddress.IPv4Address('127.0.0.1')
addr2 = ipaddress.IPv6Address('2001:db8::1')
self.assertEqual('1.0.0.127.in-addr.arpa', addr1.reverse_pointer)
self.assertEqual('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.' +
'b.d.0.1.0.0.2.ip6.arpa',
addr2.reverse_pointer)
for addr_v4, expected in [
('127.0.0.1', '1.0.0.127.in-addr.arpa'),
# test vector: https://www.rfc-editor.org/rfc/rfc1035, §3.5
('10.2.0.52', '52.0.2.10.in-addr.arpa'),
]:
with self.subTest('ipv4_reverse_pointer', addr=addr_v4):
addr = ipaddress.IPv4Address(addr_v4)
self.assertEqual(addr.reverse_pointer, expected)

for addr_v6, expected in [
(
'2001:db8::1', (
'1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.'
'0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.'
'ip6.arpa'
)
),
(
'::FFFF:192.168.1.35', (
'3.2.1.0.8.a.0.c.f.f.f.f.0.0.0.0.'
'0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.'
'ip6.arpa'
)
),
# test vector: https://www.rfc-editor.org/rfc/rfc3596, §2.5
(
'4321:0:1:2:3:4:567:89ab', (
'b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.'
'2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.'
'ip6.arpa'
)
)
]:
with self.subTest('ipv6_reverse_pointer', addr=addr_v6):
addr = ipaddress.IPv6Address(addr_v6)
self.assertEqual(addr.reverse_pointer, expected)

def testIntRepresentation(self):
self.assertEqual(16909060, int(self.ipv4_address))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :attr:`ipaddress.IPv6Address.reverse_pointer` output according to
:rfc:`RFC 3596, §2.5 <3596#section-2.5>`. Patch by Bénédikt Tran.

0 comments on commit d3f2b53

Please sign in to comment.