Fix ipv4/6 special canonicalizers to reformat IP addresses even

when a non-CIDR address is used.  Before, it left plain IP
addresses untouched.
pull/1/head
Michael Chisholm 2020-08-13 16:22:24 -04:00
parent 5d6c7d8c8a
commit 6c92f670cb
1 changed files with 50 additions and 38 deletions

View File

@ -124,15 +124,20 @@ def ipv4_addr(comp_expr):
if _path_is(comp_expr.lhs, ("value",)):
value = comp_expr.rhs.value
slash_idx = value.find("/")
is_cidr = slash_idx >= 0
if 0 <= slash_idx < len(value)-1:
if is_cidr:
ip_str = value[:slash_idx]
try:
ip_bytes = socket.inet_aton(ip_str)
except OSError:
# illegal IPv4 address string
return
else:
ip_str = value
try:
ip_bytes = socket.inet_aton(ip_str)
except OSError:
# illegal IPv4 address string
return
if is_cidr:
try:
prefix_size = int(value[slash_idx+1:])
except ValueError:
@ -143,22 +148,23 @@ def ipv4_addr(comp_expr):
# illegal prefix size
return
if prefix_size == 32:
# Drop the "32" since it's redundant. Run the address bytes
# through inet_ntoa() in case it would adjust the format (e.g.
# drop leading zeros: 1.2.3.004 => 1.2.3.4).
value = socket.inet_ntoa(ip_bytes)
if not is_cidr or prefix_size == 32:
# If a CIDR with prefix size 32, drop the prefix size since it's
# redundant. Run the address bytes through inet_ntoa() in case it
# would adjust the format (e.g. drop leading zeros:
# 1.2.3.004 => 1.2.3.4).
value = socket.inet_ntoa(ip_bytes)
else:
# inet_aton() gives an immutable 'bytes' value; we need a value
# we can change.
ip_bytes = bytearray(ip_bytes)
_mask_bytes(ip_bytes, prefix_size)
else:
# inet_aton() gives an immutable 'bytes' value; we need a value
# we can change.
ip_bytes = bytearray(ip_bytes)
_mask_bytes(ip_bytes, prefix_size)
ip_str = socket.inet_ntoa(ip_bytes)
value = ip_str + "/" + str(prefix_size)
ip_str = socket.inet_ntoa(ip_bytes)
value = ip_str + "/" + str(prefix_size)
comp_expr.rhs.value = value
comp_expr.rhs.value = value
def ipv6_addr(comp_expr):
@ -178,15 +184,20 @@ def ipv6_addr(comp_expr):
if _path_is(comp_expr.lhs, ("value",)):
value = comp_expr.rhs.value
slash_idx = value.find("/")
is_cidr = slash_idx >= 0
if 0 <= slash_idx < len(value)-1:
if is_cidr:
ip_str = value[:slash_idx]
try:
ip_bytes = socket.inet_pton(socket.AF_INET6, ip_str)
except OSError:
# illegal IPv6 address string
return
else:
ip_str = value
try:
ip_bytes = socket.inet_pton(socket.AF_INET6, ip_str)
except OSError:
# illegal IPv6 address string
return
if is_cidr:
try:
prefix_size = int(value[slash_idx+1:])
except ValueError:
@ -197,19 +208,20 @@ def ipv6_addr(comp_expr):
# illegal prefix size
return
if prefix_size == 128:
# Drop the "128" since it's redundant. Run the IP address
# through inet_ntop() so it can reformat with the double-colons
# (and make any other adjustments) if necessary.
value = socket.inet_ntop(socket.AF_INET6, ip_bytes)
if not is_cidr or prefix_size == 128:
# If a CIDR with prefix size 128, drop the prefix size since it's
# redundant. Run the IP address through inet_ntop() so it can
# reformat with the double-colons (and make any other adjustments)
# if necessary.
value = socket.inet_ntop(socket.AF_INET6, ip_bytes)
else:
# inet_pton() gives an immutable 'bytes' value; we need a value
# we can change.
ip_bytes = bytearray(ip_bytes)
_mask_bytes(ip_bytes, prefix_size)
else:
# inet_pton() gives an immutable 'bytes' value; we need a value
# we can change.
ip_bytes = bytearray(ip_bytes)
_mask_bytes(ip_bytes, prefix_size)
ip_str = socket.inet_ntop(socket.AF_INET6, ip_bytes)
value = ip_str + "/" + str(prefix_size)
ip_str = socket.inet_ntop(socket.AF_INET6, ip_bytes)
value = ip_str + "/" + str(prefix_size)
comp_expr.rhs.value = value
comp_expr.rhs.value = value