Skip to content

Commit 7528b84

Browse files
gh-118609: Add proper error check for framelocalsproxy (#118615)
1 parent 709ca90 commit 7528b84

File tree

1 file changed

+99
-46
lines changed

1 file changed

+99
-46
lines changed

Objects/frameobject.c

Lines changed: 99 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ framelocalsproxy_setitem(PyObject *self, PyObject *key, PyObject *value)
189189

190190
assert(PyDict_Check(extra));
191191

192-
return PyDict_SetItem(extra, key, value) < 0;
192+
return PyDict_SetItem(extra, key, value);
193193
}
194194

195195
static int
@@ -200,19 +200,19 @@ framelocalsproxy_merge(PyObject* self, PyObject* other)
200200
}
201201

202202
PyObject *keys = PyMapping_Keys(other);
203-
PyObject *iter = NULL;
204-
PyObject *key = NULL;
205-
PyObject *value = NULL;
206-
207-
assert(keys != NULL);
203+
if (keys == NULL) {
204+
return -1;
205+
}
208206

209-
iter = PyObject_GetIter(keys);
207+
PyObject *iter = PyObject_GetIter(keys);
210208
Py_DECREF(keys);
211-
212209
if (iter == NULL) {
213210
return -1;
214211
}
215212

213+
PyObject *key = NULL;
214+
PyObject *value = NULL;
215+
216216
while ((key = PyIter_Next(iter)) != NULL) {
217217
value = PyObject_GetItem(other, key);
218218
if (value == NULL) {
@@ -238,12 +238,11 @@ framelocalsproxy_merge(PyObject* self, PyObject* other)
238238
}
239239

240240
static PyObject *
241-
framelocalsproxy_keys(PyObject *self, PyObject *__unused)
241+
framelocalsproxy_keys(PyObject *self, void *Py_UNUSED(ignored))
242242
{
243-
PyObject *names = PyList_New(0);
244243
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
245244
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
246-
245+
PyObject *names = PyList_New(0);
247246
if (names == NULL) {
248247
return NULL;
249248
}
@@ -260,12 +259,13 @@ framelocalsproxy_keys(PyObject *self, PyObject *__unused)
260259
}
261260

262261
// Iterate through the extra locals
263-
Py_ssize_t i = 0;
264-
PyObject *key = NULL;
265-
PyObject *value = NULL;
266-
267262
if (frame->f_extra_locals) {
268263
assert(PyDict_Check(frame->f_extra_locals));
264+
265+
Py_ssize_t i = 0;
266+
PyObject *key = NULL;
267+
PyObject *value = NULL;
268+
269269
while (PyDict_Next(frame->f_extra_locals, &i, &key, &value)) {
270270
if (PyList_Append(names, key) < 0) {
271271
Py_DECREF(names);
@@ -341,9 +341,16 @@ framelocalsproxy_richcompare(PyObject *self, PyObject *other, int op)
341341
}
342342
} else if (PyDict_Check(other)) {
343343
PyObject *dct = PyDict_New();
344-
PyObject *result = NULL;
345-
PyDict_Update(dct, self);
346-
result = PyObject_RichCompare(dct, other, op);
344+
if (dct == NULL) {
345+
return NULL;
346+
}
347+
348+
if (PyDict_Update(dct, self) < 0) {
349+
Py_DECREF(dct);
350+
return NULL;
351+
}
352+
353+
PyObject *result = PyObject_RichCompare(dct, other, op);
347354
Py_DECREF(dct);
348355
return result;
349356
}
@@ -360,14 +367,22 @@ framelocalsproxy_repr(PyObject *self)
360367
}
361368

362369
PyObject *dct = PyDict_New();
363-
PyObject *repr = NULL;
370+
if (dct == NULL) {
371+
Py_ReprLeave(self);
372+
return NULL;
373+
}
364374

365-
if (PyDict_Update(dct, self) == 0) {
366-
repr = PyObject_Repr(dct);
375+
if (PyDict_Update(dct, self) < 0) {
376+
Py_DECREF(dct);
377+
Py_ReprLeave(self);
378+
return NULL;
367379
}
368-
Py_ReprLeave(self);
369380

381+
PyObject *repr = PyObject_Repr(dct);
370382
Py_DECREF(dct);
383+
384+
Py_ReprLeave(self);
385+
371386
return repr;
372387
}
373388

@@ -379,6 +394,10 @@ framelocalsproxy_or(PyObject *self, PyObject *other)
379394
}
380395

381396
PyObject *result = PyDict_New();
397+
if (result == NULL) {
398+
return NULL;
399+
}
400+
382401
if (PyDict_Update(result, self) < 0) {
383402
Py_DECREF(result);
384403
return NULL;
@@ -407,60 +426,90 @@ framelocalsproxy_inplace_or(PyObject *self, PyObject *other)
407426
}
408427

409428
static PyObject*
410-
framelocalsproxy_values(PyObject *self, PyObject *__unused)
429+
framelocalsproxy_values(PyObject *self, void *Py_UNUSED(ignored))
411430
{
412-
PyObject *values = PyList_New(0);
413431
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
414432
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
433+
PyObject *values = PyList_New(0);
434+
if (values == NULL) {
435+
return NULL;
436+
}
415437

416438
for (int i = 0; i < co->co_nlocalsplus; i++) {
417439
PyObject *value = framelocalsproxy_getval(frame->f_frame, co, i);
418440
if (value) {
419-
PyList_Append(values, value);
441+
if (PyList_Append(values, value) < 0) {
442+
Py_DECREF(values);
443+
return NULL;
444+
}
420445
}
421446
}
422447

423448
// Iterate through the extra locals
424-
Py_ssize_t j = 0;
425-
PyObject *key = NULL;
426-
PyObject *value = NULL;
427-
428449
if (frame->f_extra_locals) {
450+
Py_ssize_t j = 0;
451+
PyObject *key = NULL;
452+
PyObject *value = NULL;
429453
while (PyDict_Next(frame->f_extra_locals, &j, &key, &value)) {
430-
PyList_Append(values, value);
454+
if (PyList_Append(values, value) < 0) {
455+
Py_DECREF(values);
456+
return NULL;
457+
}
431458
}
432459
}
433460

434461
return values;
435462
}
436463

437464
static PyObject *
438-
framelocalsproxy_items(PyObject *self, PyObject *__unused)
465+
framelocalsproxy_items(PyObject *self, void *Py_UNUSED(ignored))
439466
{
440-
PyObject *items = PyList_New(0);
441467
PyFrameObject *frame = ((PyFrameLocalsProxyObject*)self)->frame;
442468
PyCodeObject *co = _PyFrame_GetCode(frame->f_frame);
469+
PyObject *items = PyList_New(0);
470+
if (items == NULL) {
471+
return NULL;
472+
}
443473

444474
for (int i = 0; i < co->co_nlocalsplus; i++) {
445475
PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
446476
PyObject *value = framelocalsproxy_getval(frame->f_frame, co, i);
447477

448478
if (value) {
449479
PyObject *pair = PyTuple_Pack(2, name, value);
450-
PyList_Append(items, pair);
480+
if (pair == NULL) {
481+
Py_DECREF(items);
482+
return NULL;
483+
}
484+
485+
if (PyList_Append(items, pair) < 0) {
486+
Py_DECREF(items);
487+
Py_DECREF(pair);
488+
return NULL;
489+
}
490+
451491
Py_DECREF(pair);
452492
}
453493
}
454494

455495
// Iterate through the extra locals
456-
Py_ssize_t j = 0;
457-
PyObject *key = NULL;
458-
PyObject *value = NULL;
459-
460496
if (frame->f_extra_locals) {
497+
Py_ssize_t j = 0;
498+
PyObject *key = NULL;
499+
PyObject *value = NULL;
461500
while (PyDict_Next(frame->f_extra_locals, &j, &key, &value)) {
462501
PyObject *pair = PyTuple_Pack(2, key, value);
463-
PyList_Append(items, pair);
502+
if (pair == NULL) {
503+
Py_DECREF(items);
504+
return NULL;
505+
}
506+
507+
if (PyList_Append(items, pair) < 0) {
508+
Py_DECREF(items);
509+
Py_DECREF(pair);
510+
return NULL;
511+
}
512+
464513
Py_DECREF(pair);
465514
}
466515
}
@@ -588,7 +637,7 @@ framelocalsproxy_setdefault(PyObject* self, PyObject *const *args, Py_ssize_t na
588637
}
589638

590639
static PyObject*
591-
framelocalsproxy_reversed(PyObject *self, PyObject *__unused)
640+
framelocalsproxy_reversed(PyObject *self, void *Py_UNUSED(ignored))
592641
{
593642
PyObject *result = framelocalsproxy_keys(self, NULL);
594643

@@ -623,19 +672,19 @@ static PyMethodDef framelocalsproxy_methods[] = {
623672
NULL},
624673
{"__getitem__", framelocalsproxy_getitem, METH_O | METH_COEXIST,
625674
NULL},
626-
{"__reversed__", framelocalsproxy_reversed, METH_NOARGS,
675+
{"update", framelocalsproxy_update, METH_O,
627676
NULL},
628-
{"keys", framelocalsproxy_keys, METH_NOARGS,
677+
{"__reversed__", _PyCFunction_CAST(framelocalsproxy_reversed), METH_NOARGS,
629678
NULL},
630-
{"values", framelocalsproxy_values, METH_NOARGS,
679+
{"keys", _PyCFunction_CAST(framelocalsproxy_keys), METH_NOARGS,
631680
NULL},
632-
{"items", framelocalsproxy_items, METH_NOARGS,
681+
{"values", _PyCFunction_CAST(framelocalsproxy_values), METH_NOARGS,
633682
NULL},
634-
{"update", framelocalsproxy_update, METH_O,
683+
{"items", _PyCFunction_CAST(framelocalsproxy_items), METH_NOARGS,
635684
NULL},
636-
{"get", _PyCFunction_CAST(framelocalsproxy_get), METH_FASTCALL,
685+
{"get", _PyCFunction_CAST(framelocalsproxy_get), METH_FASTCALL,
637686
NULL},
638-
{"setdefault", _PyCFunction_CAST(framelocalsproxy_setdefault), METH_FASTCALL,
687+
{"setdefault", _PyCFunction_CAST(framelocalsproxy_setdefault), METH_FASTCALL,
639688
NULL},
640689
{NULL, NULL} /* sentinel */
641690
};
@@ -666,6 +715,10 @@ PyObject *
666715
_PyFrameLocalsProxy_New(PyFrameObject *frame)
667716
{
668717
PyObject* args = PyTuple_Pack(1, frame);
718+
if (args == NULL) {
719+
return NULL;
720+
}
721+
669722
PyObject* proxy = (PyObject*)framelocalsproxy_new(&PyFrameLocalsProxy_Type, args, NULL);
670723
Py_DECREF(args);
671724
return proxy;

0 commit comments

Comments
 (0)