Fix VFS use-after-move crash by using stable handles for mjVFS
Root cause: resources and default mount stored pointers tied to the public mjVFS object address. If mjVFS was moved after initialization, resource close/read paths could dereference stale pointers and crash.\n\nThis change stores a stable internal mjVFS handle inside VFS and points resources/default mount to that stable handle. It also tracks the current public owner pointer and rebinds it in Upcast so lifecycle operations (including self-destruct cleanup) target the current mjVFS address after moves.\n\nAdds regression test UserVfsTest.MoveVfsAfterOpenResource, which opens a resource, moves mjVFS, then reads/closes/deletes successfully.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <gmock/gmock.h>
|
||||
#include <gtest/gtest.h>
|
||||
@@ -286,6 +287,29 @@ TEST_F(UserVfsTest, Timestamps) {
|
||||
mj_deleteVFS(&vfs);
|
||||
}
|
||||
|
||||
TEST_F(UserVfsTest, MoveVfsAfterOpenResource) {
|
||||
mjVFS vfs;
|
||||
mj_defaultVFS(&vfs);
|
||||
|
||||
std::string buffer = "<mujoco/>";
|
||||
mj_addBufferVFS(&vfs, "model", static_cast<const void*>(buffer.c_str()),
|
||||
buffer.size());
|
||||
|
||||
mjResource* resource = mju_openResource("", "model", &vfs, nullptr, 0);
|
||||
ASSERT_THAT(resource, NotNull());
|
||||
|
||||
// Move the public mjVFS object after resources have been opened.
|
||||
mjVFS moved = std::move(vfs);
|
||||
|
||||
const void* out = nullptr;
|
||||
const int size = mju_readResource(resource, &out);
|
||||
EXPECT_GT(size, 0);
|
||||
EXPECT_THAT(out, NotNull());
|
||||
|
||||
mju_closeResource(resource);
|
||||
mj_deleteVFS(&moved);
|
||||
}
|
||||
|
||||
TEST_F(UserVfsTest, MountUnmount) {
|
||||
int test = 0;
|
||||
int expect = 0;
|
||||
|
||||
Reference in New Issue
Block a user