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:
committed by
Copybara-Service
parent
1e41bf5076
commit
aee73a9023
@@ -461,8 +461,8 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt,
|
|||||||
|
|
||||||
#define X(name) \
|
#define X(name) \
|
||||||
if ((m->name) < 0) { \
|
if ((m->name) < 0) { \
|
||||||
|
mju_free(m); \
|
||||||
mju_warning("Invalid model: negative " #name); \
|
mju_warning("Invalid model: negative " #name); \
|
||||||
mj_deleteModel(m); \
|
|
||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
MJMODEL_INTS;
|
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
|
// nbody should always be positive
|
||||||
if (m->nbody == 0) {
|
if (m->nbody == 0) {
|
||||||
|
mju_free(m);
|
||||||
mju_warning("Invalid model: nbody == 0");
|
mju_warning("Invalid model: nbody == 0");
|
||||||
mj_deleteModel(m);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// nmocap is going to get multiplied by 4, and shouldn't overflow
|
// nmocap is going to get multiplied by 4, and shouldn't overflow
|
||||||
if (m->nmocap >= INT_MAX / 4) {
|
if (m->nmocap >= INT_MAX / 4) {
|
||||||
|
mju_free(m);
|
||||||
mju_warning("Invalid model: nmocap too large");
|
mju_warning("Invalid model: nmocap too large");
|
||||||
mj_deleteModel(m);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -486,8 +486,8 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt,
|
|||||||
m->nbuffer = 0;
|
m->nbuffer = 0;
|
||||||
#define X(type, name, nr, nc) \
|
#define X(type, name, nr, nc) \
|
||||||
if (!safeAddToBufferSize(&offset, &m->nbuffer, sizeof(type), m->nr, nc)) { \
|
if (!safeAddToBufferSize(&offset, &m->nbuffer, sizeof(type), m->nr, nc)) { \
|
||||||
|
mju_free(m); \
|
||||||
mju_warning("Invalid model: " #name " too large."); \
|
mju_warning("Invalid model: " #name " too large."); \
|
||||||
mj_deleteModel(m); \
|
|
||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,6 +497,7 @@ mjModel* mj_makeModel(int nq, int nv, int nu, int na, int nbody, int njnt,
|
|||||||
// allocate buffer
|
// allocate buffer
|
||||||
m->buffer = mju_malloc(m->nbuffer);
|
m->buffer = mju_malloc(m->nbuffer);
|
||||||
if (!m->buffer) {
|
if (!m->buffer) {
|
||||||
|
mju_free(m);
|
||||||
mju_error("Could not allocate mjModel buffer");
|
mju_error("Could not allocate mjModel buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,8 +855,8 @@ static mjData* _makeData(const mjModel* m) {
|
|||||||
d->buffer = d->stack = NULL;
|
d->buffer = d->stack = NULL;
|
||||||
#define X(type, name, nr, nc) \
|
#define X(type, name, nr, nc) \
|
||||||
if (!safeAddToBufferSize(&offset, &d->nbuffer, sizeof(type), m->nr, nc)) { \
|
if (!safeAddToBufferSize(&offset, &d->nbuffer, sizeof(type), m->nr, nc)) { \
|
||||||
|
mju_free(d); \
|
||||||
mju_warning("Invalid data: " #name " too large."); \
|
mju_warning("Invalid data: " #name " too large."); \
|
||||||
mj_deleteData(d); \
|
|
||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,12 +869,15 @@ static mjData* _makeData(const mjModel* m) {
|
|||||||
// allocate buffer
|
// allocate buffer
|
||||||
d->buffer = mju_malloc(d->nbuffer);
|
d->buffer = mju_malloc(d->nbuffer);
|
||||||
if (!d->buffer) {
|
if (!d->buffer) {
|
||||||
|
mju_free(d);
|
||||||
mju_error("Could not allocate mjData buffer");
|
mju_error("Could not allocate mjData buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate stack
|
// allocate stack
|
||||||
d->stack = (mjtNum*) mju_malloc(d->nstack * sizeof(mjtNum));
|
d->stack = (mjtNum*) mju_malloc(d->nstack * sizeof(mjtNum));
|
||||||
if (!d->stack) {
|
if (!d->stack) {
|
||||||
|
mju_free(d->buffer);
|
||||||
|
mju_free(d);
|
||||||
mju_error("Could not allocate mjData stack");
|
mju_error("Could not allocate mjData stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user