Skip to content

Commit b4f8eb0

Browse files
gh-118605: Fix reference leak in FrameLocalsProxy (#118607)
Also add some error checks.
1 parent d8d9491 commit b4f8eb0

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

Objects/frameobject.c

+28-3
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ framelocalsproxy_merge(PyObject* self, PyObject* other)
232232
Py_DECREF(value);
233233
}
234234

235+
Py_DECREF(iter);
236+
235237
return 0;
236238
}
237239

@@ -242,11 +244,18 @@ framelocalsproxy_keys(PyObject *self, PyObject *__unused)
242244
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
243245
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
244246

247+
if (names == NULL) {
248+
return NULL;
249+
}
250+
245251
for (int i = 0; i < co->co_nlocalsplus; i++) {
246252
PyObject *val = framelocalsproxy_getval(frame->f_frame, co, i);
247253
if (val) {
248254
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
249-
PyList_Append(names, name);
255+
if (PyList_Append(names, name) < 0) {
256+
Py_DECREF(names);
257+
return NULL;
258+
}
250259
}
251260
}
252261

@@ -258,7 +267,10 @@ framelocalsproxy_keys(PyObject *self, PyObject *__unused)
258267
if (frame->f_extra_locals) {
259268
assert(PyDict_Check(frame->f_extra_locals));
260269
while (PyDict_Next(frame->f_extra_locals, &i, &key, &value)) {
261-
PyList_Append(names, key);
270+
if (PyList_Append(names, key) < 0) {
271+
Py_DECREF(names);
272+
return NULL;
273+
}
262274
}
263275
}
264276

@@ -306,7 +318,15 @@ framelocalsproxy_visit(PyObject *self, visitproc visit, void *arg)
306318
static PyObject *
307319
framelocalsproxy_iter(PyObject *self)
308320
{
309-
return PyObject_GetIter(framelocalsproxy_keys(self, NULL));
321+
PyObject* keys = framelocalsproxy_keys(self, NULL);
322+
if (keys == NULL) {
323+
return NULL;
324+
}
325+
326+
PyObject* iter = PyObject_GetIter(keys);
327+
Py_XDECREF(keys);
328+
329+
return iter;
310330
}
311331

312332
static PyObject *
@@ -567,6 +587,11 @@ static PyObject*
567587
framelocalsproxy_reversed(PyObject *self, PyObject *__unused)
568588
{
569589
PyObject *result = framelocalsproxy_keys(self, NULL);
590+
591+
if (result == NULL) {
592+
return NULL;
593+
}
594+
570595
if (PyList_Reverse(result) < 0) {
571596
Py_DECREF(result);
572597
return NULL;

0 commit comments

Comments
 (0)