Skip to content

Commit d0114f7

Browse files
committed
gh-139122: Propagate SafeUUID lookup errors in is_safe getter
1 parent 2a5da63 commit d0114f7

2 files changed

Lines changed: 25 additions & 0 deletions

File tree

‎Lib/test/test_uuid.py‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1753,6 +1753,28 @@ def time_func(self):
17531753

17541754
@unittest.skipUnless(c_uuid, "requires the C _uuid module")
17551755
class TestCImplementationCompat(unittest.TestCase):
1756+
def test_is_safe_lookup_error(self):
1757+
# Force the lazy SafeUUID lookup to fail before it is cached. The getter
1758+
# must propagate AttributeError and recover when the attribute returns.
1759+
# Run in a subprocess because using the failed lookup can crash Python.
1760+
assert_python_ok('-c', textwrap.dedent('''
1761+
import uuid
1762+
1763+
obj = uuid.UUID(int=1)
1764+
SafeUUID = uuid.SafeUUID
1765+
del uuid.SafeUUID
1766+
try:
1767+
try:
1768+
obj.is_safe
1769+
except AttributeError as exc:
1770+
assert 'SafeUUID' in str(exc)
1771+
else:
1772+
raise AssertionError('SafeUUID lookup unexpectedly succeeded')
1773+
finally:
1774+
uuid.SafeUUID = SafeUUID
1775+
assert obj.is_safe is SafeUUID.unknown
1776+
'''))
1777+
17561778
def test_compatibility(self):
17571779
import uuid
17581780

‎Modules/_uuidmodule.c‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,9 @@ Uuid_get_is_safe(PyObject *op, void *Py_UNUSED(closure))
11061106
uuid_state *state = get_uuid_state_by_cls(Py_TYPE(self));
11071107
if (self->is_safe == NULL) {
11081108
PyObject *SafeUUID = get_SafeUUID(state);
1109+
if (SafeUUID == NULL) {
1110+
return NULL;
1111+
}
11091112
PyObject *ret = PyObject_GetAttrString(SafeUUID, "unknown");
11101113
Py_DECREF(SafeUUID);
11111114
return ret;

0 commit comments

Comments
 (0)