Skip to content

Fix out-of-bounds slice indexing panic in InMemoryAgentBusState - #2

Open
rohith500 wants to merge 1 commit into
facebookresearch:mainfrom
rohith500:fix/in-memory-read-filtered-entries-panic
Open

rohith500 wants to merge 1 commit into
facebookresearch:mainfrom
rohith500:fix/in-memory-read-filtered-entries-panic

Conversation

@rohith500

@rohith500 rohith500 commented Sep 29, 2026 •

Copy link
Copy Markdown

Summary

Fixes #3.

In InMemoryAgentBusState::read_filtered_entries, slicing &bus[start_idx..end_idx] computed end_idx = (end_position as usize).min(bus.len()) without verifying that start_idx < bus.len().

When a consumer reads beyond the tail of a populated bus or reads an empty bus with non-zero bounds (e.g. start_position: 5, end_position: 10 on a bus with 2 entries), start_idx (5) > end_idx (2), causing Rust to panic at runtime:

thread '...' panicked at 'slice index starts at 5 but ends at 2'

Changes

  1. Defensive Bounds Check: Reject negative start_position early, and guard if start_idx >= bus.len() { return Ok((vec![], end_position)); } prior to slicing, matching the defensive behavior of fetch_entries.
  2. Safe Header Access: Avoid potential expect panic on entry truncation by using .map(|h| h.log_position + 1).unwrap_or(end_position).
  3. Unit Tests: Add unit tests directly to agentbus_simple (in_memory_agentbus_state.rs) covering empty bus reads, beyond-tail reads, negative start rejection, and pagination.
  4. Conformance Test: Add run_test_read_next_beyond_tail in agentbus_tests (test_scenarios.rs) to verify boundary and beyond-tail behavior across all 14+ AgentBus test fixtures.
  5. Warning Cleanup: Remove unused BusId imports in bus/core/src/channeled_agentbus.rs and logact/commit_service/tests/src/fixtures/grpc_bus_id_encoding.rs to ensure clean, warning-free builds under -D warnings.

Test Plan

  • cargo test -p agentbus_simple (4/4 passed)
  • cargo test -p agentbus_tests --test sim_tests -- run_test_read_next_beyond_tail (14/14 passed across all fixtures)
  • cargo check --workspace (0 errors, 0 warnings)
  • cargo fmt --all -- --check (0 formatting diffs)

Summary:
In `InMemoryAgentBusState::read_filtered_entries`, slicing `&bus[start_idx..end_idx]`
calculated `end_idx = (end_position as usize).min(bus.len())` without checking
if `start_idx < bus.len()`. When a consumer reads beyond the tail of a bus or
reads an empty bus with non-zero bounds (e.g. `start_position: 5, end_position: 10`
on a bus with 2 entries), `start_idx > end_idx`, causing Rust to panic at runtime with
`slice index starts at 5 but ends at 2`.

Fix this by:
1. Rejecting negative `start_position` early.
2. Guarding `if start_idx >= bus.len()` to return `Ok((vec![], end_position))`
   matching the defensive behavior of `fetch_entries`.
3. Making header access safe on max_entries truncation with `.map(|h| h.log_position + 1).unwrap_or(end_position)`.
4. Adding direct unit tests for `InMemoryAgentBusState` covering empty bus, beyond-tail,
   negative start, and pagination.
5. Adding an AgentBus cross-implementation conformance scenario `run_test_read_next_beyond_tail`
   in `agentbus_tests`.
6. Removing unused `BusId` imports in `bus/core/src/channeled_agentbus.rs` and
   `logact/commit_service/tests/src/fixtures/grpc_bus_id_encoding.rs` to ensure
   clean zero-warning builds.

Test Plan:
- cargo test -p agentbus_simple (4/4 passed)
- cargo test -p agentbus_tests --test sim_tests -- run_test_read_next_beyond_tail (14/14 passed across all fixtures)
- cargo check --workspace (0 errors, 0 warnings)
- cargo fmt --all -- --check (0 formatting diffs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Out-of-bounds slice indexing panic in InMemoryAgentBusState::read_filtered_entries when reading past tail

1 participant