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