Found while dogfooding the current source with the locally built cdidx.
The LSP path-resolution code has several file-access trust-boundary edge cases. Project-relative checks use ad hoc relative-path string logic, and rootless mode appears to accept any resolved file URI before reading position text. Position reads also check file length before reading, but do not guard file growth while the read proceeds.
Evidence:
src/CodeIndex/Lsp/LspServer.cs TryGetProjectRelativePath uses Path.GetRelativePath plus .. string checks instead of the shared path-casing/containment helper.
TryResolveDocumentPath returns success when _projectRoot == null, then TryReadPositionLine opens the resolved file.
TryReadPositionLine checks stream.Length before constructing a reader, then reads lines until the target.
Suggested fix: use the shared path containment comparer for rooted workspaces, document or restrict rootless trust rules, and keep position reads bounded even if files change during the read.
Found while dogfooding the current source with the locally built
cdidx.The LSP path-resolution code has several file-access trust-boundary edge cases. Project-relative checks use ad hoc relative-path string logic, and rootless mode appears to accept any resolved file URI before reading position text. Position reads also check file length before reading, but do not guard file growth while the read proceeds.
Evidence:
src/CodeIndex/Lsp/LspServer.csTryGetProjectRelativePathusesPath.GetRelativePathplus..string checks instead of the shared path-casing/containment helper.TryResolveDocumentPathreturns success when_projectRoot == null, thenTryReadPositionLineopens the resolved file.TryReadPositionLinechecksstream.Lengthbefore constructing a reader, then reads lines until the target.Suggested fix: use the shared path containment comparer for rooted workspaces, document or restrict rootless trust rules, and keep position reads bounded even if files change during the read.