Fix memory leaks in mj_makeData and mj_makeModel.

Currently, if these functions fail to allocate space for the buffer or stack, it will exit without freeing any of the memory successfully allocated so far.

PiperOrigin-RevId: 466271030
Change-Id: Id01c115ec976482ac5d28c373b5eb47d77f424be
This commit is contained in:
Saran Tunyasuvunakool
2022-08-09 00:41:38 -07:00
committed by Copybara-Service
parent 1e41bf5076
commit aee73a9023
+9 -5
View File
@@ -461,8 +461,8 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt,
#define X(name) \
if ((m->name) < 0) { \
mju_free(m); \
mju_warning("Invalid model: negative " #name); \
mj_deleteModel(m); \
return 0; \
}
MJMODEL_INTS;
@@ -470,15 +470,15 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt,
// nbody should always be positive
if (m->nbody == 0) {
mju_free(m);
mju_warning("Invalid model: nbody == 0");
mj_deleteModel(m);
return 0;
}
// nmocap is going to get multiplied by 4, and shouldn't overflow
if (m->nmocap >= INT_MAX / 4) {
mju_free(m);
mju_warning("Invalid model: nmocap too large");
mj_deleteModel(m);
return 0;
}
@@ -486,8 +486,8 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt,
m->nbuffer = 0;
#define X(type, name, nr, nc) \
if (!safeAddToBufferSize(&offset, &m->nbuffer, sizeof(type), m->nr, nc)) { \
mju_free(m); \
mju_warning("Invalid model: " #name " too large."); \
mj_deleteModel(m); \
return 0; \
}
@@ -497,6 +497,7 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt,
// allocate buffer
m->buffer = mju_malloc(m->nbuffer);
if (!m->buffer) {
mju_free(m);
mju_error("Could not allocate mjModel buffer");
}
@@ -854,8 +855,8 @@ static mjData* _makeData(const mjModel* m) {
d->buffer = d->stack = NULL;
#define X(type, name, nr, nc) \
if (!safeAddToBufferSize(&offset, &d->nbuffer, sizeof(type), m->nr, nc)) { \
mju_free(d); \
mju_warning("Invalid data: " #name " too large."); \
mj_deleteData(d); \
return 0; \
}
@@ -868,12 +869,15 @@ static mjData* _makeData(const mjModel* m) {
// allocate buffer
d->buffer = mju_malloc(d->nbuffer);
if (!d->buffer) {
mju_free(d);
mju_error("Could not allocate mjData buffer");
}
// allocate stack
d->stack = (mjtNum*) mju_malloc(d->nstack * sizeof(mjtNum));
if (!d->stack) {
mju_free(d->buffer);
mju_free(d);
mju_error("Could not allocate mjData stack");
}