From d881e9e374fc9c3ec476c9ccc53b534d9cebf24f Mon Sep 17 00:00:00 2001 From: Adrian Collister Date: Wed, 11 Feb 2026 11:06:21 -0800 Subject: [PATCH] Change `tex_adr` type to `mjtSize`. Adds a test which verifies that we can index into the texture buffer at offsets larger than can be represented by a 32-bit signed int. PiperOrigin-RevId: 868756646 Change-Id: Ibc1a2b269fce41aec370611b0aab77803837e7a8 --- doc/includes/references.h | 2 +- include/mujoco/mjmodel.h | 2 +- include/mujoco/mjxmacro.h | 2 +- python/mujoco/introspect/structs.py | 2 +- test/xml/xml_native_reader_test.cc | 26 ++++++++++++++++++++++++++ unity/Runtime/Bindings/MjBindings.cs | 2 +- wasm/tests/bindings_test.ts | 5 +++-- 7 files changed, 34 insertions(+), 7 deletions(-) diff --git a/doc/includes/references.h b/doc/includes/references.h index 9b6da3cb..548e2703 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -1441,7 +1441,7 @@ struct mjModel_ { int* tex_height; // number of rows in texture image (ntex x 1) int* tex_width; // number of columns in texture image (ntex x 1) int* tex_nchannel; // number of channels in texture image (ntex x 1) - int* tex_adr; // start address in tex_data (ntex x 1) + mjtSize* tex_adr; // start address in tex_data (ntex x 1) mjtByte* tex_data; // pixel values (ntexdata x 1) int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1) diff --git a/include/mujoco/mjmodel.h b/include/mujoco/mjmodel.h index 42638b97..7dd3c64a 100644 --- a/include/mujoco/mjmodel.h +++ b/include/mujoco/mjmodel.h @@ -1099,7 +1099,7 @@ struct mjModel_ { int* tex_height; // number of rows in texture image (ntex x 1) int* tex_width; // number of columns in texture image (ntex x 1) int* tex_nchannel; // number of channels in texture image (ntex x 1) - int* tex_adr; // start address in tex_data (ntex x 1) + mjtSize* tex_adr; // start address in tex_data (ntex x 1) mjtByte* tex_data; // pixel values (ntexdata x 1) int* tex_pathadr; // address of texture asset path; -1: none (ntex x 1) diff --git a/include/mujoco/mjxmacro.h b/include/mujoco/mjxmacro.h index 10725cfa..4780e834 100644 --- a/include/mujoco/mjxmacro.h +++ b/include/mujoco/mjxmacro.h @@ -581,7 +581,7 @@ X ( int, tex_height, ntex, 1 ) \ X ( int, tex_width, ntex, 1 ) \ X ( int, tex_nchannel, ntex, 1 ) \ - X ( int, tex_adr, ntex, 1 ) \ + X ( mjtSize, tex_adr, ntex, 1 ) \ XNV ( mjtByte, tex_data, ntexdata, 1 ) \ X ( int, tex_pathadr, ntex, 1 ) diff --git a/python/mujoco/introspect/structs.py b/python/mujoco/introspect/structs.py index c20f26d6..8a2fc4a8 100644 --- a/python/mujoco/introspect/structs.py +++ b/python/mujoco/introspect/structs.py @@ -3621,7 +3621,7 @@ STRUCTS: Mapping[str, StructDecl] = dict([ StructFieldDecl( name='tex_adr', type=PointerType( - inner_type=ValueType(name='int'), + inner_type=ValueType(name='mjtSize'), ), doc='start address in tex_data', array_extent=('ntex',), diff --git a/test/xml/xml_native_reader_test.cc b/test/xml/xml_native_reader_test.cc index 5ef94983..42cc7507 100644 --- a/test/xml/xml_native_reader_test.cc +++ b/test/xml/xml_native_reader_test.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -910,6 +911,31 @@ TEST_F(XMLReaderTest, LargeTextureTest) { mj_deleteModel(model); } +TEST_F(XMLReaderTest, LargeTextureAddressTest) { + static constexpr char xml[] = R"( + + + + + + + + )"; + + std::array error; + mjModel* model = LoadModelFromString(xml, error.data(), error.size()); + + ASSERT_THAT(model, NotNull()) << error.data(); + EXPECT_EQ(model->ntex, 2); + EXPECT_GT(model->tex_adr[1], INT32_MAX); + mj_deleteModel(model); +} + TEST_F(XMLReaderTest, IncludeAssetsTest) { static constexpr char xml[] = R"( diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 1cd5a376..119de775 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -5673,7 +5673,7 @@ public unsafe struct mjModel_ { public int* tex_height; public int* tex_width; public int* tex_nchannel; - public int* tex_adr; + public Int64* tex_adr; public byte* tex_data; public int* tex_pathadr; public int* mat_texid; diff --git a/wasm/tests/bindings_test.ts b/wasm/tests/bindings_test.ts index 9c60fbd1..8fe9afe0 100644 --- a/wasm/tests/bindings_test.ts +++ b/wasm/tests/bindings_test.ts @@ -2163,9 +2163,10 @@ describe('MuJoCo WASM Bindings', () => { try { assertExists(model); const t1 = model.tex('t1'); + const texAdr = Number(model.tex_adr[t1.id]); const expectedData = model.tex_data.slice( - model.tex_adr[t1.id], - model.tex_adr[t1.id] + + texAdr, + texAdr + model.tex_height[t1.id] * model.tex_width[t1.id] * model.tex_nchannel[t1.id]);