Skip to content

Commit 85634d7

Browse files
committed
Issue python#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.
1 parent 56517e5 commit 85634d7

5 files changed

Lines changed: 20 additions & 11 deletions

File tree

Modules/_localemodule.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,11 +257,12 @@ PyLocale_strxfrm(PyObject* self, PyObject* args)
257257
n2 = wcsxfrm(buf, s, n1);
258258
if (n2 >= (size_t)n1) {
259259
/* more space needed */
260-
buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
261-
if (!buf) {
260+
wchar_t * new_buf = PyMem_Realloc(buf, (n2+1)*sizeof(wchar_t));
261+
if (!new_buf) {
262262
PyErr_NoMemory();
263263
goto exit;
264264
}
265+
buf = new_buf;
265266
n2 = wcsxfrm(buf, s, n2+1);
266267
}
267268
result = PyUnicode_FromWideChar(buf, n2);

Modules/_randommodule.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ random_seed(RandomObject *self, PyObject *args)
210210
PyObject *masklower = NULL;
211211
PyObject *thirtytwo = NULL;
212212
PyObject *n = NULL;
213-
unsigned long *key = NULL;
213+
unsigned long *new_key, *key = NULL;
214214
unsigned long keymax; /* # of allocated slots in key */
215215
unsigned long keyused; /* # of used slots in key */
216216
int err;
@@ -287,10 +287,11 @@ random_seed(RandomObject *self, PyObject *args)
287287
PyErr_NoMemory();
288288
goto Done;
289289
}
290-
key = (unsigned long *)PyMem_Realloc(key,
290+
new_key = (unsigned long *)PyMem_Realloc(key,
291291
bigger * sizeof(*key));
292-
if (key == NULL)
292+
if (new_key == NULL)
293293
goto Done;
294+
key = new_key;
294295
keymax = bigger;
295296
}
296297
assert(keyused < keymax);

Modules/unicodedata.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -526,13 +526,16 @@ nfd_nfkd(PyObject *self, PyObject *input, int k)
526526
/* Hangul Decomposition adds three characters in
527527
a single step, so we need atleast that much room. */
528528
if (space < 3) {
529+
Py_UCS4 *new_output;
529530
osize += 10;
530531
space += 10;
531-
output = PyMem_Realloc(output, osize*sizeof(Py_UCS4));
532-
if (output == NULL) {
532+
new_output = PyMem_Realloc(output, osize*sizeof(Py_UCS4));
533+
if (new_output == NULL) {
534+
PyMem_Free(output);
533535
PyErr_NoMemory();
534536
return NULL;
535537
}
538+
output = new_output;
536539
}
537540
/* Hangul Decomposition. */
538541
if (SBase <= code && code < (SBase+SCount)) {

Objects/frameobject.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,11 +663,13 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
663663
f = free_list;
664664
free_list = free_list->f_back;
665665
if (Py_SIZE(f) < extras) {
666-
f = PyObject_GC_Resize(PyFrameObject, f, extras);
667-
if (f == NULL) {
666+
PyFrameObject *new_f = PyObject_GC_Resize(PyFrameObject, f, extras);
667+
if (new_f == NULL) {
668+
PyObject_GC_Del(f);
668669
Py_DECREF(builtins);
669670
return NULL;
670671
}
672+
f = new_f;
671673
}
672674
_Py_NewReference((PyObject *)f);
673675
}

Objects/unicodeobject.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8343,13 +8343,15 @@ charmaptranslate_makespace(Py_UCS4 **outobj, Py_ssize_t *psize,
83438343
Py_ssize_t requiredsize)
83448344
{
83458345
Py_ssize_t oldsize = *psize;
8346+
Py_UCS4 *new_outobj;
83468347
if (requiredsize > oldsize) {
83478348
/* exponentially overallocate to minimize reallocations */
83488349
if (requiredsize < 2 * oldsize)
83498350
requiredsize = 2 * oldsize;
8350-
*outobj = PyMem_Realloc(*outobj, requiredsize * sizeof(Py_UCS4));
8351-
if (*outobj == 0)
8351+
new_outobj = PyMem_Realloc(*outobj, requiredsize * sizeof(Py_UCS4));
8352+
if (new_outobj == 0)
83528353
return -1;
8354+
*outobj = new_outobj;
83538355
*psize = requiredsize;
83548356
}
83558357
return 0;

0 commit comments

Comments
 (0)