[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. |