Files
codegraph/__tests__
Colby MchenryandClaude Opus 5.5 2afee00cb0 fix(viewer): a file with % in its name opens as itself (#2933)
codegraph ui couldn't show a file whose name contains a %: 100%.ts was
refused as an unusable path, and a%20b.ts was served as changed on disk
with no lines. resolveProjectFile, the chokepoint for every file the
viewer reads, percent-decoded its path. But that path is either one the
index stored or a query value the URL parser had already decoded once,
so this was a second decode. It threw on 100%.ts and turned a%20b.ts into
a b.ts, while resolveRequestedFile looked the file up in the index by the
name as given: the bytes of a b.ts were hashed against a%20b.ts's record.

The chokepoint no longer decodes. It refuses raw control bytes, and on
Windows a backslash, then checks containment as before. Raw request
paths (the viewer's own assets) are still decoded where they are read.
The File view's /api/file/<path>, whose path the HTTP layer also decodes
once, had the same double decode and is fixed by the same change.
The POSIX half of PR #2009 (backslashes kept in names on POSIX) is left
out, as it needs a wider change and a POSIX run.

Validation on Windows 11, with a fixture holding src/a%20b.ts,
src/a b.ts and src/100%.ts:
- codegraph ui over HTTP, /api/source with the query a browser sends:
  main serves a%20b.ts as drift=true with no lines and answers 403 for
  100%.ts; the fix serves all three files as themselves, drift=false.
- Tests: 2 new tests (the chokepoint, and /api/source plus
  /api/file/<path> over HTTP) fail on main's source and pass with the
  fix. Two
  existing cases that fed an encoded ..%2f and %00 straight to the
  chokepoint now go through the URL parser's single decode, as requests
  do, and are still refused.

Reported in PR #2009 by @shrankr; this reimplements the viewer half of
the fix independently.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 18:18:41 +00:00
..