Skip to content

Avoid out-of-bounds access for future trajectory anchors - #329

Open
dddd-jh wants to merge 1 commit into
koide3:masterfrom
dddd-jh:fix/guard-future-trajectory-anchor
Open

dddd-jh wants to merge 1 commit into
koide3:masterfrom
dddd-jh:fix/guard-future-trajectory-anchor

Conversation

@dddd-jh

@dddd-jh dddd-jh commented Oct 5, 2026

Copy link
Copy Markdown

TrajectoryManager::update_anchor() indexes odom_stamps[idx] immediately after lower_bound(). When the anchor timestamp is newer than the newest cached odometry, the search returns end(), so idx == odom_stamps.size() and this reads out of bounds. The same problem occurs on a freshly constructed manager when its only timestamp is the initial zero entry.

For example, add_odom(1.0, Identity()); update_anchor(2.0, Identity()); triggers a checked-vector assertion in the current implementation. Without checked access this is undefined behavior; an anchor just beyond the newest timestamp also changed the transform incorrectly in my optimized local build.

Return before indexing when the search reaches end(). This preserves the current odometry-to-world transform and cached interpolation samples when there is no odometry coverage. No extrapolation or automatic queuing is added; callers can submit the anchor again after more odometry arrives. Exact endpoint updates, translation interpolation, quaternion interpolation and the existing pruning behavior are retained.

Adds eight regression cases using the actual trajectory implementation, covering:

  • An anchor before the first odometry input, a future anchor, the next representable timestamp after the endpoint, and repeated future anchors.
  • Retrying after additional odometry, an exact endpoint update, retained interpolation samples after pruning, and normal interpolation.
  • The resulting odometry-to-world transform, current pose and both odom2world() overloads with nontrivial rotations and translations.

tests/ is a standalone Eigen-only CMake project, so these utility tests need no ROS, CUDA, GTSAM or viewer dependencies. A separate Ubuntu GCC/Clang workflow runs them in Release mode with libstdc++ bounds assertions. Test failure checks remain active with NDEBUG.

Validation on Windows with Clang 18.1.6 and Eigen 3.4.0:

  • With libc++ bounds hardening enabled, six of the eight cases terminate on out-of-bounds access with the original source; the two in-range cases pass.
  • After the fix, the submitted standalone Release CMake project builds and all eight CTest cases pass with the same bounds hardening enabled.
  • C++ formatting, YAML and Git whitespace checks pass.

I have not built the complete GLIM library or run its ROS/viewer/SLAM pipeline locally. The existing full-build workflow is unchanged.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant