Skip to content
/ cpython Public
  • Rate limit · GitHub

    Whoa there!

    You have triggered an abuse detection mechanism.

    Please wait a few minutes before you try again;
    in some cases this may take up to an hour.

  • Notifications You must be signed in to change notification settings
  • Fork 31.4k

Commit 67b9cc8

Browse files
sir-sigurdserhiy-storchaka
authored andcommittedAug 16, 2018
bpo-34395: Fix memory leaks caused by incautious usage of PyMem_Resize(). (GH-8756)
1 parent 864a892 commit 67b9cc8

File tree

2 files changed

+22
-42
lines changed

2 files changed

+22
-42
lines changed
 

‎Modules/_csv.c

+15-36
Original file line numberDiff line numberDiff line change
@@ -555,25 +555,17 @@ parse_save_field(ReaderObj *self)
555555
static int
556556
parse_grow_buff(ReaderObj *self)
557557
{
558-
if (self->field_size == 0) {
559-
self->field_size = 4096;
560-
if (self->field != NULL)
561-
PyMem_Free(self->field);
562-
self->field = PyMem_New(Py_UCS4, self->field_size);
563-
}
564-
else {
565-
Py_UCS4 *field = self->field;
566-
if (self->field_size > PY_SSIZE_T_MAX / 2) {
567-
PyErr_NoMemory();
568-
return 0;
569-
}
570-
self->field_size *= 2;
571-
self->field = PyMem_Resize(field, Py_UCS4, self->field_size);
572-
}
573-
if (self->field == NULL) {
558+
assert((size_t)self->field_size <= PY_SSIZE_T_MAX / sizeof(Py_UCS4));
559+
560+
Py_ssize_t field_size_new = self->field_size ? 2 * self->field_size : 4096;
561+
Py_UCS4 *field_new = self->field;
562+
PyMem_Resize(field_new, Py_UCS4, field_size_new);
563+
if (field_new == NULL) {
574564
PyErr_NoMemory();
575565
return 0;
576566
}
567+
self->field = field_new;
568+
self->field_size = field_size_new;
577569
return 1;
578570
}
579571

@@ -1089,31 +1081,18 @@ join_append_data(WriterObj *self, unsigned int field_kind, void *field_data,
10891081
static int
10901082
join_check_rec_size(WriterObj *self, Py_ssize_t rec_len)
10911083
{
1092-
1093-
if (rec_len < 0 || rec_len > PY_SSIZE_T_MAX - MEM_INCR) {
1094-
PyErr_NoMemory();
1095-
return 0;
1096-
}
1084+
assert(rec_len >= 0);
10971085

10981086
if (rec_len > self->rec_size) {
1099-
if (self->rec_size == 0) {
1100-
self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1101-
if (self->rec != NULL)
1102-
PyMem_Free(self->rec);
1103-
self->rec = PyMem_New(Py_UCS4, self->rec_size);
1104-
}
1105-
else {
1106-
Py_UCS4* old_rec = self->rec;
1107-
1108-
self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1109-
self->rec = PyMem_Resize(old_rec, Py_UCS4, self->rec_size);
1110-
if (self->rec == NULL)
1111-
PyMem_Free(old_rec);
1112-
}
1113-
if (self->rec == NULL) {
1087+
size_t rec_size_new = (size_t)(rec_len / MEM_INCR + 1) * MEM_INCR;
1088+
Py_UCS4 *rec_new = self->rec;
1089+
PyMem_Resize(rec_new, Py_UCS4, rec_size_new);
1090+
if (rec_new == NULL) {
11141091
PyErr_NoMemory();
11151092
return 0;
11161093
}
1094+
self->rec = rec_new;
1095+
self->rec_size = (Py_ssize_t)rec_size_new;
11171096
}
11181097
return 1;
11191098
}

‎Modules/_pickle.c

+7-6
Original file line numberDiff line numberDiff line change
@@ -1382,11 +1382,13 @@ _Unpickler_ResizeMemoList(UnpicklerObject *self, Py_ssize_t new_size)
13821382

13831383
assert(new_size > self->memo_size);
13841384

1385-
PyMem_RESIZE(self->memo, PyObject *, new_size);
1386-
if (self->memo == NULL) {
1385+
PyObject **memo_new = self->memo;
1386+
PyMem_RESIZE(memo_new, PyObject *, new_size);
1387+
if (memo_new == NULL) {
13871388
PyErr_NoMemory();
13881389
return -1;
13891390
}
1391+
self->memo = memo_new;
13901392
for (i = self->memo_size; i < new_size; i++)
13911393
self->memo[i] = NULL;
13921394
self->memo_size = new_size;
@@ -6295,11 +6297,10 @@ load_mark(UnpicklerObject *self)
62956297
return -1;
62966298
}
62976299

6298-
if (self->marks == NULL)
6299-
self->marks = PyMem_NEW(Py_ssize_t, alloc);
6300-
else
6301-
PyMem_RESIZE(self->marks, Py_ssize_t, alloc);
6300+
Py_ssize_t *marks_old = self->marks;
6301+
PyMem_RESIZE(self->marks, Py_ssize_t, alloc);
63026302
if (self->marks == NULL) {
6303+
PyMem_FREE(marks_old);
63036304
self->marks_size = 0;
63046305
PyErr_NoMemory();
63056306
return -1;

0 commit comments

Comments
 (0)
Failed to load comments.