Repository navigation
fix: accept files under Windows drive-root projects (Z:\, C:\) - #415
Kamilslaoui93 wants to merge 1 commit into
Conversation
`path.resolve('Z:\')` returns `Z:\` — a path already terminated with
the OS separator. The existing path-within-root check appended another
`path.sep`, producing `Z:\`, which no file under the root could ever
start with. Every file got rejected as a path-traversal attempt, so
`codegraph index` on a project at a drive root (or a mapped network
drive) emitted "Path traversal blocked in batch reader" for every file
and indexed nothing.
Same bug in `isPathWithinRoot` and `isPathWithinRootReal`. Fixed by
extracting an `ensureTrailingSep()` helper that only appends a
separator if one isn't already present.
Regression tests in __tests__/security.test.ts:
- Windows-gated, run only if Z:\ exists on the runner
- Cross-platform traversal-rejection tests still pass (existing
behavior preserved)
|
PR describes all three functions fixed, but only two were actually changed:
isPathWithinRootReal internally calls isPathWithinRoot (fixed), so the logical path check for the drive root will pass; However, the subsequent realpath secondary verification (realPath.startsWith(realRoot + path.sep)) will still reproduce the same bug on the drive root and does not close the project scenario with symlink. |
A project at the root of a drive, such as a mapped network drive Z:\, a
subst drive or a UNC share root, indexed nothing on Windows: every file
was refused as "Path traversal blocked", and code reads under the root
were refused too. The containment check appended a separator to the root
before comparing, and a root such as C:\ already ends with one, so the
prefix became C:\\ and no path under the root matched. The dead code
report's default file reader had its own copy of the same check, so it
treated every file of such a project as unreadable.
The check now adds a separator only when the root doesn't already end
with one. The dead code reader uses the shared lexical containment check
instead of its own copy.
Validation on Windows 11:
- subst R: onto a two-file fixture, then codegraph init -y --force R:\:
main indexes 0 files ("all 2 files had errors", 2 "Path traversal
blocked"), and validatePathWithinRoot(R:\, a.ts) is null. The fix
indexes both files (6 nodes, 6 edges) and getCode returns both
functions' source. The mapping was removed after each run.
- Dead code report against one R:\ index: main's reader drops the unused
function as unreadable; the fix reports it.
- Tests: 3 new tests fail on main's source and pass with the fix: a file
under the filesystem root (this drive's root here, / on POSIX), path
math under Q:\ and \\server\share\, and read-only realpaths under C:\.
Reported in PR #415 by @Kamilslaoui93; this reimplements the fix
independently.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks @Kamilslaoui93, you pinned down exactly why a project at a drive root indexed nothing: the root already ends with a separator, so appending another one matched no file. We landed the fix in #2931, reimplemented independently and credited to you in the changelog. It also fixes the dead-code reader, which had its own copy of the same check, and its tests run without a mapped drive. Closing this in favor of it; it ships in the next release. |
Summary
codegraph indexfails on any project located at a Windows drive root (e.g.C:\,Z:\, or a mapped network drive). Every file is rejected by the path-traversal check, indexing produces zero results, and the log fills withPath traversal blocked in batch readerfor every file in the project.Root cause
path.resolve('Z:\')returnsZ:\— a path that already ends withpath.sep. The existing check appended another separator:…producing
Z:\for drive roots. No real file path under the drive root starts withZ:\, so the check fails for every file. For non-root projects (C:\Users\foo\proj) the appended separator is correct and the check works; the bug is specific to roots whose resolved form already terminates withpath.sep.Same bug existed in
isPathWithinRootandisPathWithinRootReal.Fix
Extract a small
ensureTrailingSep()helper that appendspath.seponly when missing, and use it at all three call sites insrc/utils.ts. Behaviour is unchanged for every non-drive-root project.Reproduction
With this patch applied locally I get:
Tests
Added 4 cases to
__tests__/security.test.tsunder a newPath-within-root helpers — Windows drive-root regressiondescribe block:Z:\), skipped on POSIX and on Windows runners whereZ:\isn't mounted.../escape.txt) are still rejected — guarding against the obvious failure mode of an over-eager fix.Full
__tests__/security.test.tspasses locally on Windows (41 passed, 2 POSIX-gated skipped).Test plan
npx vitest run __tests__/security.test.ts— 41 passednpx tsc --noEmit— cleannpx codegraph indexon a project atZ:\(mapped network drive) — 768 files indexed, 0 path-traversal warnings