Check if there's enough data in the buffer before reading fields while loading MJB.

Before this change, loading a truncated MJB file would crash with mjERROR. After this change it will just return NULL.

PiperOrigin-RevId: 572928724
Change-Id: I9611eaffcc2e5ef1b957f48162ce2ef29619e087
This commit is contained in:
Nimrod Gileadi
2023-10-12 09:27:53 -07:00
committed by Copybara-Service
parent 6f8128dc6a
commit 60fd6a3298
+19 -1
View File
@@ -770,6 +770,11 @@ mjModel* mj_loadModel(const char* filename, const mjVFS* vfs) {
}
// read mjModel structure: info only
if (ptrbuf + sizeof(int)*getnint() + sizeof(size_t)*getnsize() > buffer_sz) {
mju_closeResource(r);
mju_warning("Truncated model file - ran out of data while reading sizes");
return NULL;
}
bufread(ints, sizeof(int)*getnint(), buffer_sz, buffer, &ptrbuf);
bufread(sizes, sizeof(size_t)*getnsize(), buffer_sz, buffer, &ptrbuf);
@@ -802,13 +807,26 @@ mjModel* mj_loadModel(const char* filename, const mjVFS* vfs) {
}
// read options and buffer
if (ptrbuf + sizeof(mjOption) + sizeof(mjVisual) + sizeof(mjStatistic) > buffer_sz) {
mju_closeResource(r);
mju_warning("Truncated model file - ran out of data while reading structs");
return NULL;
}
bufread((void*)&m->opt, sizeof(mjOption), buffer_sz, buffer, &ptrbuf);
bufread((void*)&m->vis, sizeof(mjVisual), buffer_sz, buffer, &ptrbuf);
bufread((void*)&m->stat, sizeof(mjStatistic), buffer_sz, buffer, &ptrbuf);
{
MJMODEL_POINTERS_PREAMBLE(m)
#define X(type, name, nr, nc) \
#define X(type, name, nr, nc) \
if (ptrbuf + sizeof(type) * (m->nr) * (nc) > buffer_sz) { \
mju_closeResource(r); \
mju_warning( \
"Truncated model file - ran out of data while reading " #name); \
mj_deleteModel(m); \
return NULL; \
} \
bufread(m->name, sizeof(type)*(m->nr)*(nc), buffer_sz, buffer, &ptrbuf);
MJMODEL_POINTERS
#undef X
}