Skip to content

Commit

Permalink
pythongh-101531: Handle omitted leading zeroes in mac address on Darw…
Browse files Browse the repository at this point in the history
  • Loading branch information
evgeniiz321 authored and Evgenii Zaiats committed Mar 31, 2024
1 parent bfc57d4 commit 73d7513
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 28 deletions.
74 changes: 50 additions & 24 deletions Lib/test/test_uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,29 +781,14 @@ class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
class BaseTestInternals:
_uuid = py_uuid

def check_parse_mac(self, aix):
if not aix:
patch = mock.patch.multiple(self.uuid,
_MAC_DELIM=b':',
_MAC_OMITS_LEADING_ZEROES=False)
else:
patch = mock.patch.multiple(self.uuid,
_MAC_DELIM=b'.',
_MAC_OMITS_LEADING_ZEROES=True)
def check_parse_mac(self, valid_macs, delim=b':', omits_leading_zeros=False):
patch = mock.patch.multiple(self.uuid,
_MAC_DELIM=delim,
_MAC_OMITS_LEADING_ZEROES=omits_leading_zeros)

with patch:
# Valid MAC addresses
if not aix:
tests = (
(b'52:54:00:9d:0e:67', 0x5254009d0e67),
(b'12:34:56:78:90:ab', 0x1234567890ab),
)
else:
# AIX format
tests = (
(b'fe.ad.c.1.23.4', 0xfead0c012304),
)
for mac, expected in tests:
for mac, expected in valid_macs:
self.assertEqual(self.uuid._parse_mac(mac), expected)

# Invalid MAC addresses
Expand All @@ -822,16 +807,38 @@ def check_parse_mac(self, aix):
# dash separator
b'52-54-00-9d-0e-67',
):
if aix:
mac = mac.replace(b':', b'.')
if delim != b':':
mac = mac.replace(b':', delim)
with self.subTest(mac=mac):
self.assertIsNone(self.uuid._parse_mac(mac))

def test_parse_mac(self):
self.check_parse_mac(False)
self.check_parse_mac(
valid_macs=(
(b'52:54:00:9d:0e:67', 0x5254009d0e67),
(b'12:34:56:78:90:ab', 0x1234567890ab),
),
delim=b':',
omits_leading_zeros=False,
)

def test_parse_mac_aix(self):
self.check_parse_mac(True)
self.check_parse_mac(
valid_macs=(
(b'fe.ad.c.1.23.4', 0xfead0c012304),
),
delim=b'.',
omits_leading_zeros=True,
)

def test_parse_mac_macos(self):
self.check_parse_mac(
valid_macs=(
(b'1:0:5e:0:c:fb', 0x01005e000cfb)
),
delim=b':',
omits_leading_zeros=True,
)

def test_find_under_heading(self):
data = '''\
Expand Down Expand Up @@ -916,6 +923,25 @@ def test_find_mac_near_keyword(self):
)

self.assertEqual(mac, 0x1234567890ab)

def test_find_mac_near_keyword_macos(self):
data = '''
? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet]
'''

with mock.patch.multiple(self.uuid,
_MAC_DELIM=b':',
_MAC_OMITS_LEADING_ZEROES=True,
_get_command_stdout=mock_get_command_stdout(data)):

mac = self.uuid._find_mac_near_keyword(
command='arp',
args='-an',
keywords=[os.fsencode('(%s)' % '224.0.0.251')],
get_word_index=lambda x: x + 2,
)

self.assertEqual(mac, 0x01005e0000fb)

def check_node(self, node, requires=None):
if requires and node is None:
Expand Down
12 changes: 8 additions & 4 deletions Lib/uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
if _AIX:
_MAC_DELIM = b'.'
_MAC_OMITS_LEADING_ZEROES = True
if sys.platform == 'darwin':
_MAC_OMITS_LEADING_ZEROES = True

RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
'reserved for NCS compatibility', 'specified in RFC 4122',
Expand Down Expand Up @@ -430,16 +432,16 @@ def _find_mac_near_keyword(command, args, keywords, get_word_index):
if words[i] in keywords:
try:
word = words[get_word_index(i)]
mac = int(word.replace(_MAC_DELIM, b''), 16)
except (ValueError, IndexError):
mac = _parse_mac(word)
except IndexError:
# Virtual interfaces, such as those provided by
# VPNs, do not have a colon-delimited MAC address
# as expected, but a 16-byte HWAddr separated by
# dashes. These should be ignored in favor of a
# real MAC address
pass
else:
if _is_universal(mac):
if mac and _is_universal(mac):
return mac
first_local_mac = first_local_mac or mac
return first_local_mac or None
Expand All @@ -456,10 +458,12 @@ def _parse_mac(word):
if len(parts) != 6:
return
if _MAC_OMITS_LEADING_ZEROES:
# (Only) on AIX the macaddr value given is not prefixed by 0, e.g.
# on AIX and darwin the macaddr value given is not prefixed by 0, e.g. on AIX
# en0 1500 link#2 fa.bc.de.f7.62.4 110854824 0 160133733 0 0
# not
# en0 1500 link#2 fa.bc.de.f7.62.04 110854824 0 160133733 0 0
# and on darwin
# ? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet]
if not all(1 <= len(part) <= 2 for part in parts):
return
hexstr = b''.join(part.rjust(2, b'0') for part in parts)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Handle omitted leading zeroes in mac address on Darwin

0 comments on commit 73d7513

Please sign in to comment.