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]
else:
ip_str = value
try: try:
ip_bytes = socket.inet_aton(ip_str) ip_bytes = socket.inet_aton(ip_str)
except OSError: except OSError:
# illegal IPv4 address string # illegal IPv4 address string
return 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,10 +148,11 @@ 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:
# 1.2.3.004 => 1.2.3.4).
value = socket.inet_ntoa(ip_bytes) value = socket.inet_ntoa(ip_bytes)
else: else:
@ -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]
else:
ip_str = value
try: try:
ip_bytes = socket.inet_pton(socket.AF_INET6, ip_str) ip_bytes = socket.inet_pton(socket.AF_INET6, ip_str)
except OSError: except OSError:
# illegal IPv6 address string # illegal IPv6 address string
return 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,10 +208,11 @@ 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)
# if necessary.
value = socket.inet_ntop(socket.AF_INET6, ip_bytes) value = socket.inet_ntop(socket.AF_INET6, ip_bytes)
else: else: