From: sobolevn Date: Fri, 7 Feb 2025 09:59:52 +0000 (+0300) Subject: gh-129766: Fix crash on calling `warnings._release_lock` with no lock (#129771) X-Git-Tag: v3.14.0a5~72 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ae132edc296d27c6ed04fe4d400c67e3cfb622e8;p=thirdparty%2FPython%2Fcpython.git gh-129766: Fix crash on calling `warnings._release_lock` with no lock (#129771) --- diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py index 4bd164b8a9a8..6f4c569d2476 100644 --- a/Lib/test/test_warnings/__init__.py +++ b/Lib/test/test_warnings/__init__.py @@ -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().""" diff --git a/Misc/NEWS.d/next/Library/2025-02-07-10-34-09.gh-issue-129766.6n5fQZ.rst b/Misc/NEWS.d/next/Library/2025-02-07-10-34-09.gh-issue-129766.6n5fQZ.rst new file mode 100644 index 000000000000..76e908300a85 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-02-07-10-34-09.gh-issue-129766.6n5fQZ.rst @@ -0,0 +1,2 @@ +Fix crash in :mod:`warnings`, when calling ``_release_lock()`` with no +existing lock. diff --git a/Python/_warnings.c b/Python/_warnings.c index bb195da9512c..891db2743a28 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -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; }