bpo-34395: Fix memory leaks caused by incautious usage of PyMem_Resiz… · python/cpython@67b9cc8

@@ -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);

1097108510981086

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

}