Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-132710: only use stable _uuid.generate_time_safe() to deduce MAC address #132901

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Lib/test/test_uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

from test import support
from test.support import import_helper
from test.support.script_helper import assert_python_ok

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


@unittest.skipUnless(c_uuid, 'requires the C _uuid module')
class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
uuid = c_uuid

def check_has_stable_libuuid_extractable_node(self):
if not self.uuid._has_stable_extractable_node:
self.skipTest("libuuid cannot deduce MAC address")

@unittest.skipUnless(os.name == 'posix', 'POSIX only')
def test_unix_getnode_from_libuuid(self):
self.check_has_stable_libuuid_extractable_node()
script = 'import uuid; print(uuid._unix_getnode())'
_, n_a, _ = assert_python_ok('-c', script)
_, n_b, _ = assert_python_ok('-c', script)
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
self.assertTrue(n_a.isdigit())
self.assertTrue(n_b.isdigit())
self.assertEqual(n_a, n_b)

@unittest.skipUnless(os.name == 'nt', 'Windows only')
def test_windows_getnode_from_libuuid(self):
self.check_has_stable_libuuid_extractable_node()
script = 'import uuid; print(uuid._windll_getnode())'
_, n_a, _ = assert_python_ok('-c', script)
_, n_b, _ = assert_python_ok('-c', script)
n_a, n_b = n_a.decode().strip(), n_b.decode().strip()
self.assertTrue(n_a.isdigit())
self.assertTrue(n_b.isdigit())
self.assertEqual(n_a, n_b)


class BaseTestInternals:
_uuid = py_uuid
Expand Down
6 changes: 4 additions & 2 deletions Lib/uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -633,22 +633,24 @@ def _netstat_getnode():
try:
import _uuid
_generate_time_safe = getattr(_uuid, "generate_time_safe", None)
_has_stable_extractable_node = _uuid.has_stable_extractable_node
_UuidCreate = getattr(_uuid, "UuidCreate", None)
except ImportError:
_uuid = None
_generate_time_safe = None
_has_stable_extractable_node = False
_UuidCreate = None


def _unix_getnode():
"""Get the hardware address on Unix using the _uuid extension module."""
if _generate_time_safe:
if _generate_time_safe and _has_stable_extractable_node:
uuid_time, _ = _generate_time_safe()
return UUID(bytes=uuid_time).node

def _windll_getnode():
"""Get the hardware address on Windows using the _uuid extension module."""
if _UuidCreate:
if _UuidCreate and _has_stable_extractable_node:
uuid_bytes = _UuidCreate()
return UUID(bytes_le=uuid_bytes).node

Expand Down
40 changes: 32 additions & 8 deletions Modules/_uuidmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,47 @@ py_UuidCreate(PyObject *Py_UNUSED(context),
return NULL;
}

static int
py_windows_has_stable_node(void)
{
UUID uuid;
RPC_STATUS res;
Py_BEGIN_ALLOW_THREADS
res = UuidCreateSequential(&uuid);
Py_END_ALLOW_THREADS
return res == RPC_S_OK;
}
#endif /* MS_WINDOWS */


static int
uuid_exec(PyObject *module) {
uuid_exec(PyObject *module)
{
#define ADD_INT(NAME, VALUE) \
do { \
if (PyModule_AddIntConstant(module, (NAME), (VALUE)) < 0) { \
return -1; \
} \
} while (0)

assert(sizeof(uuid_t) == 16);
#if defined(MS_WINDOWS)
int has_uuid_generate_time_safe = 0;
ADD_INT("has_uuid_generate_time_safe", 0);
#elif defined(HAVE_UUID_GENERATE_TIME_SAFE)
int has_uuid_generate_time_safe = 1;
ADD_INT("has_uuid_generate_time_safe", 1);
#else
int has_uuid_generate_time_safe = 0;
ADD_INT("has_uuid_generate_time_safe", 0);
#endif
if (PyModule_AddIntConstant(module, "has_uuid_generate_time_safe",
has_uuid_generate_time_safe) < 0) {
return -1;
}

#if defined(MS_WINDOWS)
ADD_INT("has_stable_extractable_node", py_windows_has_stable_node());
#elif defined(HAVE_UUID_GENERATE_TIME_SAFE_STABLE_MAC)
ADD_INT("has_stable_extractable_node", 1);
#else
ADD_INT("has_stable_extractable_node", 0);
#endif

#undef ADD_INT
return 0;
}

Expand Down
Loading
Loading