Skip to content

Commit ae1f012

Browse files
sir-sigurdserhiy-storchaka
authored andcommitted
bpo-34395: Fix memory leaks caused by incautious usage of PyMem_Realloc(). (GH-8785)
1 parent 2ec530c commit ae1f012

File tree

1 file changed

+24
-32
lines changed

1 file changed

+24
-32
lines changed

Modules/_csv.c

Lines changed: 24 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -565,24 +565,23 @@ parse_save_field(ReaderObj *self)
565565
static int
566566
parse_grow_buff(ReaderObj *self)
567567
{
568-
if (self->field_size == 0) {
569-
self->field_size = 4096;
570-
if (self->field != NULL)
571-
PyMem_Free(self->field);
572-
self->field = PyMem_Malloc(self->field_size);
573-
}
574-
else {
575-
if (self->field_size > INT_MAX / 2) {
576-
PyErr_NoMemory();
577-
return 0;
578-
}
579-
self->field_size *= 2;
580-
self->field = PyMem_Realloc(self->field, self->field_size);
568+
unsigned field_size_new;
569+
char *field_new;
570+
571+
assert((unsigned)self->field_size <= INT_MAX);
572+
573+
field_size_new = self->field_size ? 2 * (unsigned)self->field_size : 4096;
574+
if (field_size_new > INT_MAX) {
575+
PyErr_NoMemory();
576+
return 0;
581577
}
582-
if (self->field == NULL) {
578+
field_new = (char *)PyMem_Realloc(self->field, field_size_new);
579+
if (field_new == NULL) {
583580
PyErr_NoMemory();
584581
return 0;
585582
}
583+
self->field = field_new;
584+
self->field_size = (int)field_size_new;
586585
return 1;
587586
}
588587

@@ -1088,31 +1087,24 @@ join_append_data(WriterObj *self, char *field, int quote_empty,
10881087
static int
10891088
join_check_rec_size(WriterObj *self, int rec_len)
10901089
{
1090+
unsigned rec_size_new;
1091+
char *rec_new;
10911092

1092-
if (rec_len < 0 || rec_len > INT_MAX - MEM_INCR) {
1093-
PyErr_NoMemory();
1094-
return 0;
1095-
}
1093+
assert(rec_len >= 0);
10961094

10971095
if (rec_len > self->rec_size) {
1098-
if (self->rec_size == 0) {
1099-
self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1100-
if (self->rec != NULL)
1101-
PyMem_Free(self->rec);
1102-
self->rec = PyMem_Malloc(self->rec_size);
1103-
}
1104-
else {
1105-
char *old_rec = self->rec;
1106-
1107-
self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;
1108-
self->rec = PyMem_Realloc(self->rec, self->rec_size);
1109-
if (self->rec == NULL)
1110-
PyMem_Free(old_rec);
1096+
rec_size_new = (unsigned)(rec_len / MEM_INCR + 1) * MEM_INCR;
1097+
if (rec_size_new > INT_MAX) {
1098+
PyErr_NoMemory();
1099+
return 0;
11111100
}
1112-
if (self->rec == NULL) {
1101+
rec_new = (char *)PyMem_Realloc(self->rec, rec_size_new);
1102+
if (rec_new == NULL) {
11131103
PyErr_NoMemory();
11141104
return 0;
11151105
}
1106+
self->rec = rec_new;
1107+
self->rec_size = (int)rec_size_new;
11161108
}
11171109
return 1;
11181110
}

0 commit comments

Comments
 (0)