{{ message }}
Repository navigation
fix(pdf-server): resolve Windows file:// URLs to the right path - #816
Open
tzipora-rose wants to merge 1 commit into
Open
tzipora-rose wants to merge 1 commit into
tzipora-rose wants to merge 1 commit into
Conversation
fileUrlToPath() only stripped the scheme, so file:///C:/x became "/C:/x", which path.resolve() turns into C:\C:\x on Windows. Every client root was then dropped by refreshRoots(), and file:// arguments to display_pdf, save_as and save_pdf resolved to the wrong path. On win32, drop the slash before a drive letter after decoding. The URLs pathToFileUrl() builds, POSIX paths and other platforms are unchanged. Co-Authored-By: Claudia <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

This fixes the second Windows bug reported in a comment on #644, the one #805 leaves out of scope.
fileUrlToPath()only strips the scheme. For a Windows file URL that leaves a slash before the drive letter, andpath.resolve()then reads the result as a path on the current drive:refreshRoots()stats that path, the stat fails, and the root is skipped without a message, so on Windows no client root is ever added. The same helper convertsfile://URLs invalidateUrl(),readPdfRange(),display_pdf's writability check, image annotations,save_asandsave_pdf, so all of those resolve the same wrong way.Fix
On Windows, after decoding, drop the slash when it comes right before a drive letter (
/C:/x->C:/x). Nothing else changes:pathToFileUrl()builds on Windows (file://C%3A%5C..., the whole path encoded) still decode toC:\..., so CLI-arg directories still round-trip;#or?stays part of the path, as before.fileUrlToPath()takes the platform as an optional second argument (defaultprocess.platform), so the Windows behavior is unit-tested on every OS.The comment on #644 suggests Node's
url.fileURLToPath(). I didn't use it because it changes more than this bug: it throws on the URLspathToFileUrl()builds (ERR_INVALID_URLforfile://C%3A%5CUsers%5Ctest), and it cuts a path at an unencoded#or?(file:///C:/Docs/Report #3.pdf->C:\Docs\Report), which the current code accepts. Checked in Node 24.16.0 and Bun 1.3.10.Tests
A new
describe("fileUrlToPath")inexamples/pdf-server/server.test.ts:computer://) withplatformset to"win32";pathToFileUrl()form and POSIX paths unchanged;node:url'spathToFileURL()and throughpathToFileUrl();it.skipIf), a client that declaresrootssends a root built withpathToFileURL(), and after the initialize handshake the directory must be inallowedLocalDirs.On Windows 10 with Bun 1.3.10: the pdf-server tests pass (96 pass, 2 skipped). With
server.tsfrommainand the new tests, 5 of the 7 new tests fail; the two that pass check that nothing else changed.npm test: 445 pass, 2 skipped.tsc --noEmitpasses for both of the example's tsconfigs, and Prettier reports no changes.The same change, applied as a patch to the pdf-viewer extension that Claude Desktop installs, has also run inside the app on Windows 10 (Claude Desktop 2.42304.0.0, pdf-viewer 1.7.4, 1.7.5 and 2.0.0): the app's root
file:///C:/arrives and the server logsRoot directory allowed: C:\. That patch is part of a toolkit we published for people who need it before a fix ships: https://github.com/tzipora-rose/pdf-local-readNot in this PR
clear()inrefreshRoots()that wipes CLI-arg directories (v1.7.0 refreshRoots() clears allowedLocalDirs when host advertises roots capability but returns empty list — wipes CLI-arg directories #644), which fix(pdf-server): keep CLI-arg directories across client roots refreshes #805 fixes. The two PRs change different lines and work together: with both, a Windows client's roots and the CLI-arg directories are allowed side by side.file://server/share/dir), which still resolve to a relative path, as before.Investigated and written in collaboration with Claudia in Claude Code.