Skip to content

Commit 072f50f

Browse files
authored
[3.14] gh-132710: only use stable _uuid.generate_time_safe() to deduce MAC address (GH-132901) (#134697)
(cherry picked from commit 3bffada)
1 parent c8379c7 commit 072f50f

File tree

6 files changed

+357
-28
lines changed

6 files changed

+357
-28
lines changed

Lib/test/test_uuid.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
from test import support
1616
from test.support import import_helper
17+
from test.support.script_helper import assert_python_ok
1718

1819
py_uuid = import_helper.import_fresh_module('uuid', blocked=['_uuid'])
1920
c_uuid = import_helper.import_fresh_module('uuid', fresh=['_uuid'])
@@ -1217,10 +1218,37 @@ def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self):
12171218
class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase):
12181219
uuid = py_uuid
12191220

1221+
12201222
@unittest.skipUnless(c_uuid, 'requires the C _uuid module')
12211223
class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
12221224
uuid = c_uuid
12231225

1226+
def check_has_stable_libuuid_extractable_node(self):
1227+
if not self.uuid._has_stable_extractable_node:
1228+
self.skipTest("libuuid cannot deduce MAC address")
1229+
1230+
@unittest.skipUnless(os.name == 'posix', 'POSIX only')
1231+
def test_unix_getnode_from_libuuid(self):
1232+
self.check_has_stable_libuuid_extractable_node()
1233+
script = 'import uuid; print(uuid._unix_getnode())'
1234+
_, n_a, _ = assert_python_ok('-c', script)
1235+
_, n_b, _ = assert_python_ok('-c', script)
1236+
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
1237+
self.assertTrue(n_a.isdigit())
1238+
self.assertTrue(n_b.isdigit())
1239+
self.assertEqual(n_a, n_b)
1240+
1241+
@unittest.skipUnless(os.name == 'nt', 'Windows only')
1242+
def test_windows_getnode_from_libuuid(self):
1243+
self.check_has_stable_libuuid_extractable_node()
1244+
script = 'import uuid; print(uuid._windll_getnode())'
1245+
_, n_a, _ = assert_python_ok('-c', script)
1246+
_, n_b, _ = assert_python_ok('-c', script)
1247+
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
1248+
self.assertTrue(n_a.isdigit())
1249+
self.assertTrue(n_b.isdigit())
1250+
self.assertEqual(n_a, n_b)
1251+
12241252

12251253
class BaseTestInternals:
12261254
_uuid = py_uuid

Lib/uuid.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,22 +633,24 @@ def _netstat_getnode():
633633
try:
634634
import _uuid
635635
_generate_time_safe = getattr(_uuid, "generate_time_safe", None)
636+
_has_stable_extractable_node = _uuid.has_stable_extractable_node
636637
_UuidCreate = getattr(_uuid, "UuidCreate", None)
637638
except ImportError:
638639
_uuid = None
639640
_generate_time_safe = None
641+
_has_stable_extractable_node = False
640642
_UuidCreate = None
641643

642644

643645
def _unix_getnode():
644646
"""Get the hardware address on Unix using the _uuid extension module."""
645-
if _generate_time_safe:
647+
if _generate_time_safe and _has_stable_extractable_node:
646648
uuid_time, _ = _generate_time_safe()
647649
return UUID(bytes=uuid_time).node
648650

649651
def _windll_getnode():
650652
"""Get the hardware address on Windows using the _uuid extension module."""
651-
if _UuidCreate:
653+
if _UuidCreate and _has_stable_extractable_node:
652654
uuid_bytes = _UuidCreate()
653655
return UUID(bytes_le=uuid_bytes).node
654656

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy