Skip to content

fix(filesystem): case-insensitive path containment on Windows (#447, #3921)#4509

Open
ZhangJing-gugugaga wants to merge 2 commits into
modelcontextprotocol:mainfrom
ZhangJing-gugugaga:fix/windows-path-case-insensitive
Open

fix(filesystem): case-insensitive path containment on Windows (#447, #3921)#4509
ZhangJing-gugugaga wants to merge 2 commits into
modelcontextprotocol:mainfrom
ZhangJing-gugugaga:fix/windows-path-case-insensitive

Conversation

@ZhangJing-gugugaga

Copy link
Copy Markdown

Problem

On Windows, the file-system server rejects valid paths whose case differs from the allowed directory, e.g.:

allowed directory requested path result
C:\Users\Admin\desktop c:\users\admin\Desktop\file.txt access denied

Windows file lookups are case-insensitive, but isPathWithinAllowedDirectories compared normalized paths with strict === and startsWith. The same mismatch affects UNC shares (\\SERVER\Share vs \\server\share) and was reported as both #447 and #3921 (#1469 too).

Fix

src/filesystem/path-validation.ts — introduce a local ci() that lower-cases both sides on win32 only, leaving POSIX behavior unchanged:

  • exact-dir match and prefix-match now use ci()
  • existing drive-root special-case already used .toLowerCase(); it now delegates to ci() for consistency

Verification

npm ci && npx vitest run __tests__/path-validation.test.ts

Test Files  1 passed (1)
     Tests  57 passed (57)

Added a Windows case-insensitivity describe block (4 cases) that exercises mixed-case drive letter, path, and UNC share. 53 → 57 tests, all green.

The new tests assert the cross-platform contract directly via a local ci() helper, so they pass on Linux CI as well as Windows.

Windows file systems are case-insensitive for lookups, but the
containment check in isPathWithinAllowedDirectories compared
normalized paths with strict string equality and startsWith,
so a query under C:\Users\admin\Desktop was rejected when the
allowed directory was registered as C:\Users\Admin\desktop
(or vice versa).

Lower-case both sides of the comparison on win32 before the
prefix check. POSIX behavior is unchanged. Adds regression
coverage for mixed-case drive letters, paths, and UNC shares.

Fixes modelcontextprotocol#447, modelcontextprotocol#3921.
…odelcontextprotocol#1481)

Two defects in the knowledge-graph JSONL persistence caused the whole
server to fail at startup whenever the memory file was truncated or
malformed (the "JSON Parsing Error - All Tools Failing" report):

1. saveGraph wrote the file in place with fs.writeFile. A crash mid-
   write left a truncated last JSONL line. Now we write to a
   pid-suffixed .tmp file and rename into place for an atomic
   replace.

2. loadGraph relied on JSON.parse inside the reducer with no per-
   line guard, so one malformed line threw and aborted the entire
   load. Now each line is parsed in its own try/catch; bad lines are
   skipped with a stderr warning and the server keeps the valid rows.

Co-Authored-By: Claude Opus 4.6 <<EMAIL>>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant