Merge "reject leading '0's in IPv4 addr to avoid ambiguity"
This commit is contained in:
commit
6dc9a79579
neutron
@ -211,7 +211,10 @@ def _validate_mac_address_or_none(data, valid_values=None):
|
||||
def _validate_ip_address(data, valid_values=None):
|
||||
msg = None
|
||||
try:
|
||||
netaddr.IPAddress(_validate_no_whitespace(data))
|
||||
# netaddr.core.ZEROFILL is only applicable to IPv4.
|
||||
# it will remove leading zeros from IPv4 address octets.
|
||||
ip = netaddr.IPAddress(_validate_no_whitespace(data),
|
||||
flags=netaddr.core.ZEROFILL)
|
||||
# The followings are quick checks for IPv6 (has ':') and
|
||||
# IPv4. (has 3 periods like 'xx.xx.xx.xx')
|
||||
# NOTE(yamamoto): netaddr uses libraries provided by the underlying
|
||||
@ -227,6 +230,13 @@ def _validate_ip_address(data, valid_values=None):
|
||||
# >>>
|
||||
if ':' not in data and data.count('.') != 3:
|
||||
msg = _("'%s' is not a valid IP address") % data
|
||||
# A leading '0' in IPv4 address may be interpreted as an octal number,
|
||||
# e.g. 011 octal is 9 decimal. Since there is no standard saying
|
||||
# whether IP address with leading '0's should be interpreted as octal
|
||||
# or decimal, hence we reject leading '0's to avoid ambiguity.
|
||||
if ip.version == 4 and str(ip) != data:
|
||||
msg = _("'%(data)s' is not an accepted IP address, "
|
||||
"'%(ip)s' is recommended") % {"data": data, "ip": ip}
|
||||
except Exception:
|
||||
msg = _("'%s' is not a valid IP address") % data
|
||||
if msg:
|
||||
|
@ -17,6 +17,7 @@ import string
|
||||
import testtools
|
||||
|
||||
import mock
|
||||
import netaddr
|
||||
|
||||
from neutron._i18n import _
|
||||
from neutron.api.v2 import attributes
|
||||
@ -270,6 +271,28 @@ class TestAttributes(base.BaseTestCase):
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)
|
||||
|
||||
def test_validate_ip_address_with_leading_zero(self):
|
||||
ip_addr = '1.1.1.01'
|
||||
expected_msg = ("'%(data)s' is not an accepted IP address, "
|
||||
"'%(ip)s' is recommended")
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual(expected_msg % {"data": ip_addr, "ip": '1.1.1.1'},
|
||||
msg)
|
||||
|
||||
ip_addr = '1.1.1.011'
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual(expected_msg % {"data": ip_addr, "ip": '1.1.1.11'},
|
||||
msg)
|
||||
|
||||
ip_addr = '1.1.1.09'
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertEqual(expected_msg % {"data": ip_addr, "ip": '1.1.1.9'},
|
||||
msg)
|
||||
|
||||
ip_addr = "fe80:0:0:0:0:0:0:0001"
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
self.assertIsNone(msg)
|
||||
|
||||
def test_validate_ip_address_bsd(self):
|
||||
# NOTE(yamamoto): On NetBSD and OS X, netaddr.IPAddress() accepts
|
||||
# '1' * 59 as a valid address. The behaviour is inherited from
|
||||
@ -279,7 +302,8 @@ class TestAttributes(base.BaseTestCase):
|
||||
ip_addr = '1' * 59
|
||||
with mock.patch('netaddr.IPAddress') as ip_address_cls:
|
||||
msg = attributes._validate_ip_address(ip_addr)
|
||||
ip_address_cls.assert_called_once_with(ip_addr)
|
||||
ip_address_cls.assert_called_once_with(ip_addr,
|
||||
flags=netaddr.core.ZEROFILL)
|
||||
self.assertEqual("'%s' is not a valid IP address" % ip_addr, msg)
|
||||
|
||||
def test_validate_ip_pools(self):
|
||||
|
Loading…
x
Reference in New Issue
Block a user