fix(bridge): bound disk I/O in position-encoding conversion - #486
Merged
Merged
Conversation
This was referenced Sep 21, 2026
bug-ops
force-pushed
the
position-encoding-conversion-re
branch
from
September 21, 2026 12:19
49d4646 to
3e40015
Compare
bug-ops
enabled auto-merge (squash)
September 21, 2026 12:19
Converting an LSP location to MCP coordinates fell through to a whole-file disk read with no cache whenever the target line wasn't already in DocumentTracker's in-memory state, and every response looped over every returned location with no cap. A hostile or malfunctioning LSP server could turn one references/goto/workspace- symbol/call-hierarchy/inlay-hints/rename response into on the order of a terabyte of disk I/O for a single MCP tool call. Line text read from disk is now memoized per (path, line) for the lifetime of one response, and read incrementally instead of loading the whole file. A per-response byte budget bounds total disk I/O across every EncodingCtx-mediated handler regardless of how many distinct files or lines are touched, charged as bytes are scanned so it cannot be bypassed by a failed read (invalid UTF-8, size-limit truncation, or a nonexistent path). References, goto-definition/ implementation/type-definition, and workspace-symbol additionally cap the number of locations/symbols normalized per response and report truncation to the caller via a new `truncated` field.
bug-ops
force-pushed
the
position-encoding-conversion-re
branch
from
September 21, 2026 12:24
3e40015 to
9823864
Compare
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.
Summary
Converting an LSP location to MCP coordinates fell through to a whole-file disk read with no cache whenever the target line wasn't already in
DocumentTracker's in-memory state, and every response looped over every returned location with no cap. A hostile or malfunctioning LSP server could turn onereferences/goto/workspace-symbol/call-hierarchy/inlay-hints/rename response into on the order of a terabyte of disk I/O for a single MCP tool call (CWE-405, CWE-770).(path, line)for the lifetime of one response, and read incrementally instead of loading the whole file.EncodingCtx-mediated handler, charged as bytes are scanned so it cannot be bypassed by a failed read (invalid UTF-8, size-limit truncation, or a nonexistent path).references, goto-definition/implementation/type-definition, andworkspace-symboladditionally cap the number of locations/symbols normalized per response and report truncation to the caller via a newtruncatedfield.Follow-ups filed separately (out of scope for this PR, by agreement during review)
call_hierarchy/inlay-hints/workspace-edit handlers have no item-count cap (their disk I/O is bounded by the shared byte budget; in-memory conversions for a huge item count are not).max_file_size.Test plan
cargo +nightly fmt --all -- --checkcargo clippy --all-targets --all-features --workspace -- -D warningscargo nextest run --workspace --all-features --lib --bins(968 passed, 1 skipped)RUSTDOCFLAGS="-D warnings --deny rustdoc::broken_intra_doc_links" cargo doc --no-deps --all-featuresCloses #474