Repository navigation
fix(path-validation): normalize Windows paths case-insensitively (#1689) - #1882
anisayakmitra-in wants to merge 3 commits into
Conversation
nc-review: comments — 2 important, 1 nit@anisayakmitra-in — a few things worth a look, none blocking. The PR adds a 🟠 important · The This is the failure mode the project rubric names: a test that names a failure path but never triggers it. Fix: add 🟠 important · The first assertion of this test is a tautology — it compares the same call to itself and cannot fail: t.is(
normalizeForCompare('/Proj/App', 'linux'),
normalizeForCompare('/Proj/App', 'linux'),
);The test name claims "preserves case on posix" but nothing checks it, and nothing else in the suite would catch a regression either: if Fix: assert the property, e.g. ⚪ nit ·
That is a reasonable seam, but it puts the security semantics of a containment check under caller control: 🔴 blocking · 🟠 a reviewer would ask for a change · ⚪ optional Automated code review — correctness, security, design, tests, plus duplicates and scope. A human still decides; this is not a substitute for review and is not exhaustive. The required status checks separately cover lint, formatting, types, unused dependencies, the test suite and the build. This bot never merges. Maintainers can rerun with |
|
Thanks @nc-review! Addressed in commit 2318183:
|
| platform: NodeJS.Platform = process.platform, | ||
| ): string { | ||
| const resolved = path.resolve(p); // nosemgrep | ||
| return platform === 'win32' ? resolved.toLowerCase() : resolved; |
There was a problem hiding this comment.
L213: 🟡 risk: Lowercasing every Win32 path collapses distinct entries in case-sensitive NTFS directories (Windows supports per-directory case sensitivity: https://learn.microsoft.com/en-us/windows/wsl/case-sensitivity), so a sibling can pass this trusted-root check. Does Nanocoder explicitly exclude that filesystem mode? If so, please document it; otherwise add a guard/regression so the trust boundary preserves actual filesystem semantics. Codex-assisted review; checked exact head 2318183.
|
Thanks @ducanhnguyen223! Addressed in commit 83617a6: Nanocoder's We have updated the docstrings in source/utils/path-validation.ts and the changeset to explicitly document that lexical normalization assumes standard Win32 case-insensitivity and excludes NTFS per-directory case-sensitivity modes, pointing callers to isRealPathInside whenever filesystem-level case semantics must be enforced. |
Summary
Fixes #1689.
Windows filesystem paths are case-insensitive, but Nanocoder compared them strictly as case-sensitive text (
===andstartsWith). On Windows, passing an absolute path or working in a directory whose drive letter or folder name differed only in case (e.g.c:\work\projvsC:\Work\Proj) resulted in:isDirectoryTrustedreturningfalsefor previously trusted directories and re-prompting.isValidFilePathandresolveFilePathrejecting valid absolute paths withInvalid file path: ....trustRecheckfailing to recognize recorded entries.trustedDirectorieswhen saved with varying casing.Proposed Changes
source/utils/path-validation.ts:normalizeForCompare(p, platform = process.platform)helper that resolves paths and lowercases them onwin32.isPathInside(target, root, platform = process.platform)to usenormalizeForCompareso containment checks on Windows respect case-insensitivity without affecting POSIX platforms.source/config/preferences.ts:normalizeForCompareinisDirectoryTrusted,trustRecheck,grantDirectoryTrust, andisProjectPreferencesPath.source/daemon/full-commit-trust.ts:normalizeForComparefromsource/utils/path-validation.ts.source/utils/path-validation.spec.tsverifying cross-platformnormalizeForCompareand Windows path containment case-insensitivity forisPathInside,isValidFilePath, andresolveFilePath.source/config/preferences.spec.tsverifying case-insensitive matching inisDirectoryTrusted,trustRecheck, and deduplication ingrantDirectoryTrust..changeset/windows-path-case-sensitivity.md.Verification
ava source/config/preferences.spec.ts source/utils/path-validation.spec.ts --match "*case*").pnpm run test:types,test:types:voice,test:types:vscode) passes with 0 errors.npx biome check) passes with 0 errors.