fix(datacell, odescent): fix multiple out-of-bounds array accesses#2364
Hidden character warning
Conversation
Merge Protections🟢 All 3 merge protections satisfied — ready to merge. Show 3 satisfied protections🟢 Require kind label
🟢 Require version label
🟢 Require linked issue for feature/bug PRs
|
There was a problem hiding this comment.
Code Review
This pull request introduces critical bounds checks to prevent potential out-of-bounds accesses in GraphDataCell, SparseTermDataCell, and ODescent. In odescent_graph_builder.cpp, the proposed check for replace_pos can be improved; instead of skipping the repair entirely when the index is out of bounds, capping the index to the maximum valid neighbor list size allows the repair logic to continue functioning correctly.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
Pull request overview
This PR fixes three boundary-condition out-of-bounds array/vector access bugs in the C++ src/ implementation (GraphDataCell delete/recover, ODescent graph repair, and SparseTermDataCell doc pruning), aligning behavior with the intended container bounds and eliminating undefined behavior paths described in issue #2363.
Changes:
- Fix an off-by-one capacity check in
GraphDataCell::{DeleteNeighborsById, RecoverDeleteNeighborsById}(<=→<). - Add post-
update_neighbors()size guards inODescent::repair_no_in_edge()to avoid indexing beyond actual neighbor list lengths. - Bound
SparseTermDataCell::DocPrune()’s accumulation loop to prevent walking pastsorted_base.size().
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/datacell/graph_datacell.h | Tightens ID bound checks to prevent OOB access to node_versions_ on the capacity boundary. |
| src/impl/odescent/odescent_graph_builder.cpp | Adds container-size-based guards in repair_no_in_edge() to prevent OOB reads after neighbor list compaction. |
| src/datacell/sparse_term_datacell.cpp | Adds loop bound in DocPrune() so pruning cannot read past the end of sorted_base. |
Three boundary-condition fixes in src/: GraphDataCell uses `<=` where `<` is required to keep the index inside `node_versions_`; ODescent `repair_no_in_edge` does not check the post-`update_neighbors` linker sizes when traversing and indexing into `graph_[...].neighbors`; SparseTermDataCell `DocPrune` accumulates mass without bounding `pruned_doc_len` against the container size, which can read past the end on near-1.0 ratios due to floating-point error. All three changes only add or tighten boundary checks and do not affect behavior on normal paths. Signed-off-by: opencode <opencode@anthropic.com> Co-authored-by: opencode <opencode@anthropic.com>
b4bf1d8 to
1335cad
Compare
Summary
Fix three out-of-bounds array/vector accesses in
src/:src/datacell/graph_datacell.h:DeleteNeighborsById/RecoverDeleteNeighborsByIduseid <= max_capacity_, allowingid == max_capacity_which is one past the end ofnode_versions_.src/impl/odescent/odescent_graph_builder.cpp:ODescent::repair_no_in_edgereadslink[need_replace_loc]andgraph_[...].neighbors[replace_pos[...]]without verifying the post-update_neighborsactual container sizes.src/datacell/sparse_term_datacell.cpp:SparseTermDataCell::DocPruneaccumulatessorted_base[i].seconduntiltemp_mass >= part_mass; floating-point error neardoc_retain_ratio_ = 1.0can pushpruned_doc_lenpast the end.All changes are minimal boundary-condition fixes and do not affect normal-path behavior.
Fixes #2363
Changes
Verification
make fmtpasses.github/main.(Build/Test steps skipped on operator instruction due to local environment limitations; reviewers are asked to run CI.)