Skip to content

Commit 524d28a

Browse files
committed
[3.13] gh-132710: only use stable _uuid.generate_time_safe() to deduce MAC address (GH-132901)
(cherry picked from commit 3bffada) Co-authored-by: Bénédikt Tran <[email protected]>
1 parent 08e1ba8 commit 524d28a

File tree

6 files changed

+379
-24
lines changed

6 files changed

+379
-24
lines changed

Lib/test/test_uuid.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import unittest
22
from test import support
33
from test.support import import_helper
4+
from test.support.script_helper import assert_python_ok
45
import builtins
56
import contextlib
67
import copy
@@ -773,10 +774,37 @@ def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self):
773774
class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase):
774775
uuid = py_uuid
775776

777+
776778
@unittest.skipUnless(c_uuid, 'requires the C _uuid module')
777779
class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
778780
uuid = c_uuid
779781

782+
def check_has_stable_libuuid_extractable_node(self):
783+
if not self.uuid._has_stable_extractable_node:
784+
self.skipTest("libuuid cannot deduce MAC address")
785+
786+
@unittest.skipUnless(os.name == 'posix', 'POSIX only')
787+
def test_unix_getnode_from_libuuid(self):
788+
self.check_has_stable_libuuid_extractable_node()
789+
script = 'import uuid; print(uuid._unix_getnode())'
790+
_, n_a, _ = assert_python_ok('-c', script)
791+
_, n_b, _ = assert_python_ok('-c', script)
792+
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
793+
self.assertTrue(n_a.isdigit())
794+
self.assertTrue(n_b.isdigit())
795+
self.assertEqual(n_a, n_b)
796+
797+
@unittest.skipUnless(os.name == 'nt', 'Windows only')
798+
def test_windows_getnode_from_libuuid(self):
799+
self.check_has_stable_libuuid_extractable_node()
800+
script = 'import uuid; print(uuid._windll_getnode())'
801+
_, n_a, _ = assert_python_ok('-c', script)
802+
_, n_b, _ = assert_python_ok('-c', script)
803+
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
804+
self.assertTrue(n_a.isdigit())
805+
self.assertTrue(n_b.isdigit())
806+
self.assertEqual(n_a, n_b)
807+
780808

781809
class BaseTestInternals:
782810
_uuid = py_uuid

Lib/uuid.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,22 +572,24 @@ def _netstat_getnode():
572572
try:
573573
import _uuid
574574
_generate_time_safe = getattr(_uuid, "generate_time_safe", None)
575+
_has_stable_extractable_node = _uuid.has_stable_extractable_node
575576
_UuidCreate = getattr(_uuid, "UuidCreate", None)
576577
except ImportError:
577578
_uuid = None
578579
_generate_time_safe = None
580+
_has_stable_extractable_node = False
579581
_UuidCreate = None
580582

581583

582584
def _unix_getnode():
583585
"""Get the hardware address on Unix using the _uuid extension module."""
584-
if _generate_time_safe:
586+
if _generate_time_safe and _has_stable_extractable_node:
585587
uuid_time, _ = _generate_time_safe()
586588
return UUID(bytes=uuid_time).node
587589

588590
def _windll_getnode():
589591
"""Get the hardware address on Windows using the _uuid extension module."""
590-
if _UuidCreate:
592+
if _UuidCreate and _has_stable_extractable_node:
591593
uuid_bytes = _UuidCreate()
592594
return UUID(bytes_le=uuid_bytes).node
593595

Modules/_uuidmodule.c

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,47 @@ py_UuidCreate(PyObject *Py_UNUSED(context),
7878
return NULL;
7979
}
8080

81+
static int
82+
py_windows_has_stable_node(void)
83+
{
84+
UUID uuid;
85+
RPC_STATUS res;
86+
Py_BEGIN_ALLOW_THREADS
87+
res = UuidCreateSequential(&uuid);
88+
Py_END_ALLOW_THREADS
89+
return res == RPC_S_OK;
90+
}
8191
#endif /* MS_WINDOWS */
8292

8393

8494
static int
85-
uuid_exec(PyObject *module) {
95+
uuid_exec(PyObject *module)
96+
{
97+
#define ADD_INT(NAME, VALUE) \
98+
do { \
99+
if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \
100+
return -1; \
101+
} \
102+
} while (0)
103+
86104
assert(sizeof(uuid_t) == 16);
87105
#if defined(MS_WINDOWS)
88-
int has_uuid_generate_time_safe = 0;
106+
ADD_INT("has_uuid_generate_time_safe", 0);
89107
#elif defined(HAVE_UUID_GENERATE_TIME_SAFE)
90-
int has_uuid_generate_time_safe = 1;
108+
ADD_INT("has_uuid_generate_time_safe", 1);
91109
#else
92-
int has_uuid_generate_time_safe = 0;
110+
ADD_INT("has_uuid_generate_time_safe", 0);
93111
#endif
94-
if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe",
95-
has_uuid_generate_time_safe) < 0) {
96-
return -1;
97-
}
112+
113+
#if defined(MS_WINDOWS)
114+
ADD_INT("has_stable_extractable_node", py_windows_has_stable_node());
115+
#elif defined(HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC)
116+
ADD_INT("has_stable_extractable_node", 1);
117+
#else
118+
ADD_INT("has_stable_extractable_node", 0);
119+
#endif
120+
121+
#undef ADD_INT
98122
return 0;
99123
}
100124

0 commit comments

Comments
 (0)