From 59bc74ca5914f3158112564ce5f43a1630ab7dd9 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sun, 5 May 2024 12:25:55 -0700 Subject: [PATCH 1/3] Fix reference leak in FrameLocalsProxy --- Objects/frameobject.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 1cb00e318d9163..08f3ff5ce4c2e5 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -232,6 +232,8 @@ framelocalsproxy_merge(PyObject* self, PyObject* other) Py_DECREF(value); } + Py_DECREF(iter); + return 0; } @@ -306,7 +308,10 @@ framelocalsproxy_visit(PyObject *self, visitproc visit, void *arg) static PyObject * framelocalsproxy_iter(PyObject *self) { - return PyObject_GetIter(framelocalsproxy_keys(self, NULL)); + PyObject* keys = framelocalsproxy_keys(self, NULL); + PyObject* iter = PyObject_GetIter(keys); + Py_XDECREF(keys); + return iter; } static PyObject * From a3331bb3304dfd9f54a4fbb18329daf57c380b6f Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sun, 5 May 2024 12:37:55 -0700 Subject: [PATCH 2/3] Add error check for keys --- Objects/frameobject.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 08f3ff5ce4c2e5..c78d6809641885 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -248,7 +248,10 @@ framelocalsproxy_keys(PyObject *self, PyObject *__unused) PyObject *val = framelocalsproxy_getval(frame->f_frame, co, i); if (val) { PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i); - PyList_Append(names, name); + if (PyList_Append(names, name) < 0) { + Py_DECREF(names); + return NULL; + } } } @@ -260,7 +263,10 @@ framelocalsproxy_keys(PyObject *self, PyObject *__unused) if (frame->f_extra_locals) { assert(PyDict_Check(frame->f_extra_locals)); while (PyDict_Next(frame->f_extra_locals, &i, &key, &value)) { - PyList_Append(names, key); + if (PyList_Append(names, key) < 0) { + Py_DECREF(names); + return NULL; + } } } @@ -309,8 +315,13 @@ static PyObject * framelocalsproxy_iter(PyObject *self) { PyObject* keys = framelocalsproxy_keys(self, NULL); + if (keys == NULL) { + return NULL; + } + PyObject* iter = PyObject_GetIter(keys); Py_XDECREF(keys); + return iter; } @@ -572,6 +583,11 @@ static PyObject* framelocalsproxy_reversed(PyObject *self, PyObject *__unused) { PyObject *result = framelocalsproxy_keys(self, NULL); + + if (result == NULL) { + return NULL; + } + if (PyList_Reverse(result) < 0) { Py_DECREF(result); return NULL; From a9ee0160feb39efc85f8ded358e92d8f643d9958 Mon Sep 17 00:00:00 2001 From: Tian Gao Date: Sun, 5 May 2024 14:07:45 -0700 Subject: [PATCH 3/3] Add check for PyList_New() --- Objects/frameobject.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Objects/frameobject.c b/Objects/frameobject.c index c78d6809641885..fdac86961f860c 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -244,6 +244,10 @@ framelocalsproxy_keys(PyObject *self, PyObject *__unused) PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame; PyCodeObject *co = _PyFrame_GetCode(frame->f_frame); + if (names == NULL) { + return NULL; + } + for (int i = 0; i < co->co_nlocalsplus; i++) { PyObject *val = framelocalsproxy_getval(frame->f_frame, co, i); if (val) {