Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 45 additions & 9 deletions Lib/test/test_uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ def importable(name):
return False


def mock_get_command_stdout(data):
def get_command_stdout(command, args):
return io.BytesIO(data.encode())
return get_command_stdout


class BaseTestUUID:
uuid = None

Expand Down Expand Up @@ -673,7 +679,6 @@ class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
class BaseTestInternals:
_uuid = py_uuid


def test_find_under_heading(self):
data = '''\
Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll
Expand All @@ -685,15 +690,12 @@ def test_find_under_heading(self):
224.0.0.1
'''

def mock_get_command_stdout(command, args):
return io.BytesIO(data.encode())

# The above data is from AIX - with '.' as _MAC_DELIM and strings
# shorter than 17 bytes (no leading 0). (_MAC_OMITS_LEADING_ZEROES=True)
with mock.patch.multiple(self.uuid,
_MAC_DELIM=b'.',
_MAC_OMITS_LEADING_ZEROES=True,
_get_command_stdout=mock_get_command_stdout):
_get_command_stdout=mock_get_command_stdout(data)):
mac = self.uuid._find_mac_under_heading(
command='netstat',
args='-ian',
Expand All @@ -702,6 +704,43 @@ def mock_get_command_stdout(command, args):

self.assertEqual(mac, 0xfead0c012304)

def test_find_under_heading_ipv6(self):
# bpo-39991: IPv6 address "fe80::5054:ff:fe9" looks like a MAC address
# (same string length) but must be skipped
data = '''\
Name Mtu Network Address Ipkts Ierrs Idrop Opkts Oerrs Coll
vtnet 1500 <Link#1> 52:54:00:9d:0e:67 10017 0 0 8174 0 0
vtnet - fe80::%vtnet0 fe80::5054:ff:fe9 0 - - 4 - -
vtnet - 192.168.122.0 192.168.122.45 8844 - - 8171 - -
lo0 16384 <Link#2> lo0 260148 0 0 260148 0 0
lo0 - ::1/128 ::1 193 - - 193 - -
ff01::1%lo0
ff02::2:2eb7:74fa
ff02::2:ff2e:b774
ff02::1%lo0
ff02::1:ff00:1%lo
lo0 - fe80::%lo0/64 fe80::1%lo0 0 - - 0 - -
ff01::1%lo0
ff02::2:2eb7:74fa
ff02::2:ff2e:b774
ff02::1%lo0
ff02::1:ff00:1%lo
lo0 - 127.0.0.0/8 127.0.0.1 259955 - - 259955 - -
224.0.0.1
'''

with mock.patch.multiple(self.uuid,
_MAC_DELIM=b':',
_MAC_OMITS_LEADING_ZEROES=False,
_get_command_stdout=mock_get_command_stdout(data)):
mac = self.uuid._find_mac_under_heading(
command='netstat',
args='-ian',
heading=b'Address',
)

self.assertEqual(mac, 0x5254009d0e67)

def test_find_mac_near_keyword(self):
# key and value are on the same line
data = '''
Expand All @@ -710,14 +749,11 @@ def test_find_mac_near_keyword(self):
eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
'''

def mock_get_command_stdout(command, args):
return io.BytesIO(data.encode())

# The above data will only be parsed properly on non-AIX unixes.
with mock.patch.multiple(self.uuid,
_MAC_DELIM=b':',
_MAC_OMITS_LEADING_ZEROES=False,
_get_command_stdout=mock_get_command_stdout):
_get_command_stdout=mock_get_command_stdout(data)):
mac = self.uuid._find_mac_near_keyword(
command='ifconfig',
args='',
Expand Down
5 changes: 4 additions & 1 deletion Lib/uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,10 @@ def _find_mac_under_heading(command, args, heading):
try:
words = line.rstrip().split()
word = words[column_index]
if len(word) == 17:
# Accept 'HH:HH:HH:HH:HH:HH' MAC address (ex: '52:54:00:9d:0e:67'),
# but reject IPv6 address (ex: 'fe80::5054:ff:fe9') detected
# by '::' pattern.
if len(word) == 17 and b'::' not in word:
mac = int(word.replace(_MAC_DELIM, b''), 16)
elif _MAC_OMITS_LEADING_ZEROES:
# (Only) on AIX the macaddr value given is not prefixed by 0, e.g.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:func:`uuid.getnode` now skips IPv6 addresses with the same string length
than a MAC address (17 characters): only use MAC addresses.