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
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):
"""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);
}
static inline void
static inline int
warnings_unlock(PyInterpreterState *interp)
{
WarningsState *st = warnings_get_state(interp);
assert(st != NULL);
_PyRecursiveMutex_Unlock(&st->lock);
return _PyRecursiveMutex_TryUnlock(&st->lock);
}
static inline bool
@ -284,7 +284,10 @@ warnings_release_lock_impl(PyObject *module)
if (interp == 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;
}