Issue #14909: A number of places were using PyMem_Realloc() apis and
PyObject_GC_Resize() with incorrect error handling. In case of errors,
the original object would be leaked. This checkin fixes those cases.
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 6208556..929385f 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -663,11 +663,13 @@
f = free_list;
free_list = free_list->f_back;
if (Py_SIZE(f) < extras) {
- f = PyObject_GC_Resize(PyFrameObject, f, extras);
- if (f == NULL) {
+ PyFrameObject *new_f = PyObject_GC_Resize(PyFrameObject, f, extras);
+ if (new_f == NULL) {
+ PyObject_GC_Del(f);
Py_DECREF(builtins);
return NULL;
}
+ f = new_f;
}
_Py_NewReference((PyObject *)f);
}
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 874e80e..9e9378e 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -8343,13 +8343,15 @@
Py_ssize_t requiredsize)
{
Py_ssize_t oldsize = *psize;
+ Py_UCS4 *new_outobj;
if (requiredsize > oldsize) {
/* exponentially overallocate to minimize reallocations */
if (requiredsize < 2 * oldsize)
requiredsize = 2 * oldsize;
- *outobj = PyMem_Realloc(*outobj, requiredsize * sizeof(Py_UCS4));
- if (*outobj == 0)
+ new_outobj = PyMem_Realloc(*outobj, requiredsize * sizeof(Py_UCS4));
+ if (new_outobj == 0)
return -1;
+ *outobj = new_outobj;
*psize = requiredsize;
}
return 0;