fix(fs): do not parse relative paths with a colon as URLs (#3632)

In plugins/fs/src/file_path.rs SafeFilePath::from_str, any string that
parsed as a URL with a scheme of 2+ characters was a URL, so a relative
path such as `notes:2024.txt` became a cannot-be-a-base URL and failed
with InvalidPathUrl.

Cannot-be-a-base URLs are now parsed as paths. The scheme-agnostic
url.to_file_path() stays: its result is scope checked (not a bypass).
Unit test for the parser; e2e spec writes and reads such a file (not on
Windows, where `:` is not allowed in file names).
This commit is contained in:
Lucas Fernandes Nogueira authored and GitHub committed 2026-10-10 16:06:02 -03:00
1 parent b6f39cc51c
commit 3b19ca096c
3 files changed
+65 -1

No files matched your search

+20
View File
@@ -8,6 +8,7 @@ import {
tauriError,
describePlugin,
itDesktop,
itOn,
scratchDir
} from '../helpers/index.js'
@@ -394,6 +395,25 @@ describePlugin('fs', () => {
expect(message).toMatch(/resource id \d+ is invalid/)
})
// `:` is not allowed in Windows file names
itOn(
['linux', 'darwin', 'android', 'ios'],
'relative paths that look like a URL scheme are paths',
async () => {
const result = await tauri(async (api) => {
const baseDir = api.fs.BaseDirectory.AppData
const path = 'e2e-notes:2024.txt'
await api.fs.writeTextFile(path, 'notes', { baseDir })
try {
return await api.fs.readTextFile(path, { baseDir })
} finally {
await api.fs.remove(path, { baseDir })
}
})
expect(result).toBe('notes')
}
)
it('rejects paths outside the configured scope', async () => {
// `$HOME` itself is not in the example's fs scope (only the app dirs,
// `$DOWNLOAD` and `$RESOURCE` are).