[3.6] bpo-32502: Discard 64-bit (and other invalid) hardware addresse… · python/cpython@d69794f (original) (raw)

3 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -304,6 +304,32 @@ def test_getnode(self):
304 304 node2 = uuid.getnode()
305 305 self.assertEqual(node1, node2, '%012x != %012x' % (node1, node2))
306 306
307 +# bpo-32502: UUID1 requires a 48-bit identifier, but hardware identifiers
308 +# need not necessarily be 48 bits (e.g., EUI-64).
309 +def test_uuid1_eui64(self):
310 +# Confirm that uuid.getnode ignores hardware addresses larger than 48
311 +# bits. Mock out each platform's *_getnode helper functions to return
312 +# something just larger than 48 bits to test. This will cause
313 +# uuid.getnode to fall back on uuid._random_getnode, which will
314 +# generate a valid value.
315 +too_large_getter = lambda: 1 << 48
316 +with unittest.mock.patch.multiple(
317 +uuid,
318 +_node=None, # Ignore any cached node value.
319 +_NODE_GETTERS_WIN32=[too_large_getter],
320 +_NODE_GETTERS_UNIX=[too_large_getter],
321 + ):
322 +node = uuid.getnode()
323 +self.assertTrue(0 < node < (1 << 48), '%012x' % node)
324 +
325 +# Confirm that uuid1 can use the generated node, i.e., the that
326 +# uuid.getnode fell back on uuid._random_getnode() rather than using
327 +# the value from too_large_getter above.
328 +try:
329 +uuid.uuid1(node=node)
330 +except ValueError as e:
331 +self.fail('uuid1 was given an invalid node ID')
332 +
307 333 @unittest.skipUnless(importable('ctypes'), 'requires ctypes')
308 334 def test_uuid1(self):
309 335 equal = self.assertEqual
Original file line number Diff line number Diff line change
@@ -540,6 +540,11 @@ def _random_getnode():
540 540
541 541 _node = None
542 542
543 +_NODE_GETTERS_WIN32 = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
544 +
545 +_NODE_GETTERS_UNIX = [_unixdll_getnode, _ifconfig_getnode, _ip_getnode,
546 +_arp_getnode, _lanscan_getnode, _netstat_getnode]
547 +
543 548 def getnode():
544 549 """Get the hardware address as a 48-bit positive integer.
545 550
@@ -555,18 +560,18 @@ def getnode():
555 560
556 561 import sys
557 562 if sys.platform == 'win32':
558 -getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
563 +getters = _NODE_GETTERS_WIN32
559 564 else:
560 -getters = [_unixdll_getnode, _ifconfig_getnode, _ip_getnode,
561 -_arp_getnode, _lanscan_getnode, _netstat_getnode]
565 +getters = _NODE_GETTERS_UNIX
562 566
563 567 for getter in getters + [_random_getnode]:
564 568 try:
565 569 _node = getter()
566 570 except:
567 571 continue
568 -if _node is not None:
572 +if (_node is not None) and (0 <= _node < (1 << 48)):
569 573 return _node
574 +assert False, '_random_getnode() returned invalid value: {}'.format(_node)
570 575
571 576 _last_timestamp = None
572 577
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1 +uuid.uuid1 no longer raises an exception if a 64-bit hardware address is
2 +encountered.