Skip to content

Commit de560d0

Browse files
evgeniiz321Evgenii Zaiats
authored and
Evgenii Zaiats
committed
gh-101531: Handle omitted leading zeroes in mac address on Darwin (#101531)
1 parent bfc57d4 commit de560d0

File tree

3 files changed

+59
-28
lines changed

3 files changed

+59
-28
lines changed

Lib/test/test_uuid.py

+50-24
Original file line numberDiff line numberDiff line change
@@ -781,29 +781,14 @@ class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
781781
class BaseTestInternals:
782782
_uuid = py_uuid
783783

784-
def check_parse_mac(self, aix):
785-
if not aix:
786-
patch = mock.patch.multiple(self.uuid,
787-
_MAC_DELIM=b':',
788-
_MAC_OMITS_LEADING_ZEROES=False)
789-
else:
790-
patch = mock.patch.multiple(self.uuid,
791-
_MAC_DELIM=b'.',
792-
_MAC_OMITS_LEADING_ZEROES=True)
784+
def check_parse_mac(self, valid_macs, delim=b':', omits_leading_zeros=False):
785+
patch = mock.patch.multiple(self.uuid,
786+
_MAC_DELIM=delim,
787+
_MAC_OMITS_LEADING_ZEROES=omits_leading_zeros)
793788

794789
with patch:
795790
# Valid MAC addresses
796-
if not aix:
797-
tests = (
798-
(b'52:54:00:9d:0e:67', 0x5254009d0e67),
799-
(b'12:34:56:78:90:ab', 0x1234567890ab),
800-
)
801-
else:
802-
# AIX format
803-
tests = (
804-
(b'fe.ad.c.1.23.4', 0xfead0c012304),
805-
)
806-
for mac, expected in tests:
791+
for mac, expected in valid_macs:
807792
self.assertEqual(self.uuid._parse_mac(mac), expected)
808793

809794
# Invalid MAC addresses
@@ -822,16 +807,38 @@ def check_parse_mac(self, aix):
822807
# dash separator
823808
b'52-54-00-9d-0e-67',
824809
):
825-
if aix:
826-
mac = mac.replace(b':', b'.')
810+
if delim != b':':
811+
mac = mac.replace(b':', delim)
827812
with self.subTest(mac=mac):
828813
self.assertIsNone(self.uuid._parse_mac(mac))
829814

830815
def test_parse_mac(self):
831-
self.check_parse_mac(False)
816+
self.check_parse_mac(
817+
valid_macs=(
818+
(b'52:54:00:9d:0e:67', 0x5254009d0e67),
819+
(b'12:34:56:78:90:ab', 0x1234567890ab),
820+
),
821+
delim=b':',
822+
omits_leading_zeros=False,
823+
)
832824

833825
def test_parse_mac_aix(self):
834-
self.check_parse_mac(True)
826+
self.check_parse_mac(
827+
valid_macs=(
828+
(b'fe.ad.c.1.23.4', 0xfead0c012304),
829+
),
830+
delim=b'.',
831+
omits_leading_zeros=True,
832+
)
833+
834+
def test_parse_mac_macos(self):
835+
self.check_parse_mac(
836+
valid_macs=(
837+
(b'1:0:5e:0:c:fb', 0x01005e000cfb)
838+
),
839+
delim=b':',
840+
omits_leading_zeros=True,
841+
)
835842

836843
def test_find_under_heading(self):
837844
data = '''\
@@ -917,6 +924,25 @@ def test_find_mac_near_keyword(self):
917924

918925
self.assertEqual(mac, 0x1234567890ab)
919926

927+
def test_find_mac_near_keyword_macos(self):
928+
data = '''
929+
? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet]
930+
'''
931+
932+
with mock.patch.multiple(self.uuid,
933+
_MAC_DELIM=b':',
934+
_MAC_OMITS_LEADING_ZEROES=True,
935+
_get_command_stdout=mock_get_command_stdout(data)):
936+
937+
mac = self.uuid._find_mac_near_keyword(
938+
command='arp',
939+
args='-an',
940+
keywords=[os.fsencode('(%s)' % '224.0.0.251')],
941+
get_word_index=lambda x: x + 2,
942+
)
943+
944+
self.assertEqual(mac, 0x01005e0000fb)
945+
920946
def check_node(self, node, requires=None):
921947
if requires and node is None:
922948
self.skipTest('requires ' + requires)

Lib/uuid.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
if _AIX:
7070
_MAC_DELIM = b'.'
7171
_MAC_OMITS_LEADING_ZEROES = True
72+
if sys.platform == 'darwin':
73+
_MAC_OMITS_LEADING_ZEROES = True
7274

7375
RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
7476
'reserved for NCS compatibility', 'specified in RFC 4122',
@@ -430,16 +432,16 @@ def _find_mac_near_keyword(command, args, keywords, get_word_index):
430432
if words[i] in keywords:
431433
try:
432434
word = words[get_word_index(i)]
433-
mac = int(word.replace(_MAC_DELIM, b''), 16)
434-
except (ValueError, IndexError):
435+
mac = _parse_mac(word)
436+
except IndexError:
435437
# Virtual interfaces, such as those provided by
436438
# VPNs, do not have a colon-delimited MAC address
437439
# as expected, but a 16-byte HWAddr separated by
438440
# dashes. These should be ignored in favor of a
439441
# real MAC address
440442
pass
441443
else:
442-
if _is_universal(mac):
444+
if mac and _is_universal(mac):
443445
return mac
444446
first_local_mac = first_local_mac or mac
445447
return first_local_mac or None
@@ -456,10 +458,12 @@ def _parse_mac(word):
456458
if len(parts) != 6:
457459
return
458460
if _MAC_OMITS_LEADING_ZEROES:
459-
# (Only) on AIX the macaddr value given is not prefixed by 0, e.g.
461+
# on AIX and darwin the macaddr value given is not prefixed by 0, e.g. on AIX
460462
# en0 1500 link#2 fa.bc.de.f7.62.4 110854824 0 160133733 0 0
461463
# not
462464
# en0 1500 link#2 fa.bc.de.f7.62.04 110854824 0 160133733 0 0
465+
# and on darwin
466+
# ? (224.0.0.251) at 1:0:5e:0:0:fb on en0 ifscope permanent [ethernet]
463467
if not all(1 <= len(part) <= 2 for part in parts):
464468
return
465469
hexstr = b''.join(part.rjust(2, b'0') for part in parts)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Handle omitted leading zeroes in mac address on Darwin

0 commit comments

Comments
 (0)