summaryrefslogtreecommitdiff
path: root/Modules
diff options
context:
space:
mode:
authorSergey Fedoseev <fedoseev.sergey@gmail.com>2018-08-17 10:36:15 +0500
committerSerhiy Storchaka <storchaka@gmail.com>2018-08-17 08:36:15 +0300
commitae1f0127298b1193618062fd0c8a3b434656e780 (patch)
tree8be7e228d8452638d7d218db0c7ff4190517f8d2 /Modules
parent2ec530cd5537dfda5ca0af6ac696e45013ed31d2 (diff)
downloadcpython-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.c56
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;
}