gh-129766: Fix crash on calling warnings._release_lock with no lock (#129771)

This commit is contained in:
sobolevn 2025-02-07 12:59:52 +03:00 committed by GitHub
parent e2064d6750
commit ae132edc29
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 19 additions and 3 deletions

View file

@ -1432,6 +1432,17 @@ class PyEnvironmentVariableTests(EnvironmentVariableTests, unittest.TestCase):
module = py_warnings module = py_warnings
class LocksTest(unittest.TestCase):
@support.cpython_only
@unittest.skipUnless(c_warnings, 'C module is required')
def test_release_lock_no_lock(self):
with self.assertRaisesRegex(
RuntimeError,
'cannot release un-acquired lock',
):
c_warnings._release_lock()
class _DeprecatedTest(BaseTest, unittest.TestCase): class _DeprecatedTest(BaseTest, unittest.TestCase):
"""Test _deprecated().""" """Test _deprecated()."""

View file

@ -0,0 +1,2 @@
Fix crash in :mod:`warnings`, when calling ``_release_lock()`` with no
existing lock.

View file

@ -240,12 +240,12 @@ warnings_lock(PyInterpreterState *interp)
_PyRecursiveMutex_Lock(&st->lock); _PyRecursiveMutex_Lock(&st->lock);
} }
static inline void static inline int
warnings_unlock(PyInterpreterState *interp) warnings_unlock(PyInterpreterState *interp)
{ {
WarningsState *st = warnings_get_state(interp); WarningsState *st = warnings_get_state(interp);
assert(st != NULL); assert(st != NULL);
_PyRecursiveMutex_Unlock(&st->lock); return _PyRecursiveMutex_TryUnlock(&st->lock);
} }
static inline bool static inline bool
@ -284,7 +284,10 @@ warnings_release_lock_impl(PyObject *module)
if (interp == NULL) { if (interp == NULL) {
return NULL; return NULL;
} }
warnings_unlock(interp); if (warnings_unlock(interp) < 0) {
PyErr_SetString(PyExc_RuntimeError, "cannot release un-acquired lock");
return NULL;
}
Py_RETURN_NONE; Py_RETURN_NONE;
} }