Repository navigation
fix(snapshot): restore refuses moved static geometry and voxel sensors - #425
Merged
Merged
Conversation
siracozmen01
commented
Nov 8, 2026
siracozmen01
left a comment
Collaborator
Author
There was a problem hiding this comment.
Review at a9277bb: ready, once CI goes green. I read the code and did not run it.
- The helper moves nothing.
m3ShapeIsStaticOnlyis the same four-type disjunction both sites had.ShapeContentCheckstill refuses a static-only type on a body that is not static.m3TypeChangeCheckstill runs its loop only fortype != m3_staticBodyand returnsm3_errorInvalidon the first static-only shape. So for every shape type and every body type, create and SetType give the answers they gave before. - Restore refuses what create and SetType cannot produce, and only that.
- Create puts a static-only shape only on a static body, and SetType refuses to move such a body off static. No live static-only shape can sit on a kinematic or dynamic body, and that is exactly what
StaticGeometryValidrefuses. - A static body holding such shapes is skipped. So is every other shape type, sensors of planes, meshes and height fields included, which create allows.
- It runs inside
m3SnapshotValuesValid, afterShapeListsValid(snapshot_links.c:571-573). The body index it reads has already passed that check, as its comment says.
- Create puts a static-only shape only on a static body, and SetType refuses to move such a body off static. No live static-only shape can sit on a kinematic or dynamic body, and that is exactly what
- The voxel-sensor rule matches create. Create refuses a voxel chunk with
def->isSensorboth inshape_create.c:664and inShapeContentCheck(!def->isSensor && ..., shape.c:207). It storesshapeSensorasdef->isSensor ? 1 : 0, and no setter writes it. So a live voxel chunk always hasshapeSensor == 0, andsensors[s] != 0refuses exactly the forged ones. - The forged cases. Each changes one byte the library never writes that way: the mesh's body type to kinematic, the voxel chunk's sensor byte to 1. Each expects
m3_errorFormatwith the world unchanged, through the suite's case table. The body reports that both restore with the check made to pass everything. fixwithout!fits at 1.x: restore now refuses bytes the library never writes. The body has Problem, Change and Verification, and no column-0name(line.
Whichever of this and #423 merges second takes a merge of main into test_restore_links.c, as the manager noted. That resolution needs a read before it merges.
No findings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Planes, meshes, height fields and voxel chunks are static geometry. A create puts them only on a static body, through
ShapeContentCheckinsrc/shape.c, andm3Body_SetTyperefuses to make such a body kinematic or dynamic, throughm3TypeChangeCheckinsrc/body.c. A voxel chunk is also never a sensor: create refuses a sensor def, and no setter changes a shape's sensor flag.m3World_Restorechecked neither rule. A probe on main took one shape of each kind on a static body, changed one byte of its snapshot and restored it into the same world. Each kind restored and stepped withm3_successon a body made kinematic, and a voxel chunk restored and stepped as a sensor (#424).Change
StaticGeometryValidinsrc/snapshot_values.cruns with the other value checks, after the shape lists have put every live shape's body in range and alive. It refuses, withm3_errorFormat, a live plane, mesh, height field or voxel chunk whose body is not static, and a live voxel chunk that is a sensor. A refused restore leaves the world as it was.m3ShapeIsStaticOnlyinsrc/shape.hnames the four types once. Create, the type change and restore all use it, so the three checks cannot drift apart.No step, result or golden hash moves: the check only refuses snapshots the library cannot write. Mesh, height field and plane sensors stay legal, as create allows them.
Verification
test/test_restore_links.chas two new forged cases on the fuzz scene: its mesh's body set to kinematic, and its voxel chunk set to a sensor. Each is refused with the world left as it was. The suite's existing cases still restore every snapshot the engine writes.StaticGeometryValidmade to pass everything, which is main's restore, both cases restore and the test fails. With it, a gcc-14 Debug build with-DMAUL3D_WERROR=ONpasses the test.tools/check.sh prpasses on this head, a9277bb: 78 and 76 tests, clang-tidy clean, and fuzz with no finding.Closes #424