https://github.com/python/cpython/commit/50c24913a422a8ce567b70f65517d7d098c6fecd
commit: 50c24913a422a8ce567b70f65517d7d098c6fecd
branch: main
author: Christian Aurich Zanettini Martins <[email protected]>
committer: mpage <[email protected]>
date: 2026-10-21T09:52:44-07:00
summary:

gh-159399: Fix crash in codecs.encode() on a concurrently unregistered codec 
(#159400)

* gh-159399: Fix crash in codecs.encode() on a concurrently unregistered codec

In the free-threaded build, codec_getitem() released the CodecInfo tuple
returned by _PyCodec_Lookup() before taking a reference to the encoder
or decoder it returns. If another thread cleared the lookup cache in
between with codecs.unregister(), the tuple could hold the last
reference to the item, which was then freed before it was increfed.

Take the reference before releasing the tuple, as
codec_getitem_checked() already does.

* Remove the free-threading stress test

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2026-10-14-07-36-44.gh-issue-159399.cjuE0N.rst
M Python/codecs.c

diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2026-10-14-07-36-44.gh-issue-159399.cjuE0N.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-14-07-36-44.gh-issue-159399.cjuE0N.rst
new file mode 100644
index 00000000000000..f7020fee0cbc86
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2026-10-14-07-36-44.gh-issue-159399.cjuE0N.rst
@@ -0,0 +1,3 @@
+Fix a crash in :func:`codecs.encode` and :func:`codecs.decode` in the
+:term:`free-threaded build` when another thread concurrently unregisters a
+codec search function. Patch by Christian Aurich Zanettini Martins.
diff --git a/Python/codecs.c b/Python/codecs.c
index c9802af937296e..2621a17daf1814 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -272,9 +272,9 @@ PyObject *codec_getitem(const char *encoding, int index)
     codecs = _PyCodec_Lookup(encoding);
     if (codecs == NULL)
         return NULL;
-    v = PyTuple_GET_ITEM(codecs, index);
+    v = Py_NewRef(PyTuple_GET_ITEM(codecs, index));
     Py_DECREF(codecs);
-    return Py_NewRef(v);
+    return v;
 }
 
 /* Helper functions to create an incremental codec. */

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to