diff options
author | Sergey Fedoseev <fedoseev.sergey@gmail.com> | 2018-08-17 10:36:15 +0500 |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2018-08-17 08:36:15 +0300 |
commit | ae1f0127298b1193618062fd0c8a3b434656e780 (patch) | |
tree | 8be7e228d8452638d7d218db0c7ff4190517f8d2 /Modules | |
parent | 2ec530cd5537dfda5ca0af6ac696e45013ed31d2 (diff) | |
download | cpython-git-ae1f0127298b1193618062fd0c8a3b434656e780.tar.gz |
bpo-34395: Fix memory leaks caused by incautious usage of PyMem_Realloc(). (GH-8785)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_csv.c | 56 |
1 files changed, 24 insertions, 32 deletions
diff --git a/Modules/_csv.c b/Modules/_csv.c index ea7d08931c..88e3e90658 100644 --- a/Modules/_csv.c +++ b/Modules/_csv.c @@ -565,24 +565,23 @@ parse_save_field(ReaderObj *self) static int parse_grow_buff(ReaderObj *self) { - if (self->field_size == 0) { - self->field_size = 4096; - if (self->field != NULL) - PyMem_Free(self->field); - self->field = PyMem_Malloc(self->field_size); - } - else { - if (self->field_size > INT_MAX / 2) { - PyErr_NoMemory(); - return 0; - } - self->field_size *= 2; - self->field = PyMem_Realloc(self->field, self->field_size); + unsigned field_size_new; + char *field_new; + + assert((unsigned)self->field_size <= INT_MAX); + + field_size_new = self->field_size ? 2 * (unsigned)self->field_size : 4096; + if (field_size_new > INT_MAX) { + PyErr_NoMemory(); + return 0; } - if (self->field == NULL) { + field_new = (char *)PyMem_Realloc(self->field, field_size_new); + if (field_new == NULL) { PyErr_NoMemory(); return 0; } + self->field = field_new; + self->field_size = (int)field_size_new; return 1; } @@ -1088,31 +1087,24 @@ join_append_data(WriterObj *self, char *field, int quote_empty, static int join_check_rec_size(WriterObj *self, int rec_len) { + unsigned rec_size_new; + char *rec_new; - if (rec_len < 0 || rec_len > INT_MAX - MEM_INCR) { - PyErr_NoMemory(); - return 0; - } + assert(rec_len >= 0); if (rec_len > self->rec_size) { - if (self->rec_size == 0) { - self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR; - if (self->rec != NULL) - PyMem_Free(self->rec); - self->rec = PyMem_Malloc(self->rec_size); - } - else { - char *old_rec = self->rec; - - self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR; - self->rec = PyMem_Realloc(self->rec, self->rec_size); - if (self->rec == NULL) - PyMem_Free(old_rec); + rec_size_new = (unsigned)(rec_len / MEM_INCR + 1) * MEM_INCR; + if (rec_size_new > INT_MAX) { + PyErr_NoMemory(); + return 0; } - if (self->rec == NULL) { + rec_new = (char *)PyMem_Realloc(self->rec, rec_size_new); + if (rec_new == NULL) { PyErr_NoMemory(); return 0; } + self->rec = rec_new; + self->rec_size = (int)rec_size_new; } return 1; } |