diff options
author | Donghee Na <donghee.na@python.org> | 2024-04-19 00:18:22 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-19 00:18:22 +0900 |
commit | 94444ea45a86ae46e0c11d1917c43c4c271018cd (patch) | |
tree | 603c48be6648e272d271d4f04cebaea12def1363 /Python/marshal.c | |
parent | 40f4d641a93b1cba89be4bc7b26cdb481e0450d5 (diff) | |
download | cpython-94444ea45a86ae46e0c11d1917c43c4c271018cd.tar.gz cpython-94444ea45a86ae46e0c11d1917c43c4c271018cd.zip |
gh-112069: Add _PySet_NextEntryRef to be thread-safe. (gh-117990)
Diffstat (limited to 'Python/marshal.c')
-rw-r--r-- | Python/marshal.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/Python/marshal.c b/Python/marshal.c index 21d242bbb97..4274f90206b 100644 --- a/Python/marshal.c +++ b/Python/marshal.c @@ -7,12 +7,13 @@ and sharing. */ #include "Python.h" -#include "pycore_call.h" // _PyObject_CallNoArgs() -#include "pycore_code.h" // _PyCode_New() -#include "pycore_hashtable.h" // _Py_hashtable_t -#include "pycore_long.h" // _PyLong_DigitCount -#include "pycore_setobject.h" // _PySet_NextEntry() -#include "marshal.h" // Py_MARSHAL_VERSION +#include "pycore_call.h" // _PyObject_CallNoArgs() +#include "pycore_code.h" // _PyCode_New() +#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION() +#include "pycore_hashtable.h" // _Py_hashtable_t +#include "pycore_long.h" // _PyLong_DigitCount +#include "pycore_setobject.h" // _PySet_NextEntry() +#include "marshal.h" // Py_MARSHAL_VERSION #ifdef __APPLE__ # include "TargetConditionals.h" @@ -531,23 +532,29 @@ w_complex_object(PyObject *v, char flag, WFILE *p) return; } Py_ssize_t i = 0; - while (_PySet_NextEntry(v, &pos, &value, &hash)) { + Py_BEGIN_CRITICAL_SECTION(v); + while (_PySet_NextEntryRef(v, &pos, &value, &hash)) { PyObject *dump = _PyMarshal_WriteObjectToString(value, p->version, p->allow_code); if (dump == NULL) { p->error = WFERR_UNMARSHALLABLE; - Py_DECREF(pairs); - return; + Py_DECREF(value); + break; } PyObject *pair = PyTuple_Pack(2, dump, value); Py_DECREF(dump); + Py_DECREF(value); if (pair == NULL) { p->error = WFERR_NOMEMORY; - Py_DECREF(pairs); - return; + break; } PyList_SET_ITEM(pairs, i++, pair); } + Py_END_CRITICAL_SECTION(); + if (p->error == WFERR_UNMARSHALLABLE || p->error == WFERR_NOMEMORY) { + Py_DECREF(pairs); + return; + } assert(i == n); if (PyList_Sort(pairs)) { p->error = WFERR_NOMEMORY; |