From 2b7dad1ea1d78d7977e0569fcca4c585b4014e85 Mon Sep 17 00:00:00 2001 From: Artur Date: Tue, 29 Mar 2022 12:16:52 +0300 Subject: [PATCH] fix: make @fs URLs work with special characters (#7510) --- .../fs-serve/__tests__/fs-serve.spec.ts | 16 +++++++++++ .../playground/fs-serve/root/src/index.html | 28 +++++++++++++++++++ .../safe.json" | 3 ++ .../safe.txt" | 1 + .../src/node/server/middlewares/static.ts | 2 +- 5 files changed, 49 insertions(+), 1 deletion(-) create mode 100644 "packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.json" create mode 100644 "packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.txt" diff --git a/packages/playground/fs-serve/__tests__/fs-serve.spec.ts b/packages/playground/fs-serve/__tests__/fs-serve.spec.ts index c618186b9bcd64..eba1e441881710 100644 --- a/packages/playground/fs-serve/__tests__/fs-serve.spec.ts +++ b/packages/playground/fs-serve/__tests__/fs-serve.spec.ts @@ -23,6 +23,15 @@ describe('main', () => { expect(await page.textContent('.safe-fetch-status')).toBe('200') }) + test('safe fetch with special characters', async () => { + expect( + await page.textContent('.safe-fetch-subdir-special-characters') + ).toMatch('KEY=safe') + expect( + await page.textContent('.safe-fetch-subdir-special-characters-status') + ).toBe('200') + }) + test('unsafe fetch', async () => { expect(await page.textContent('.unsafe-fetch')).toMatch('403 Restricted') expect(await page.textContent('.unsafe-fetch-status')).toBe('403') @@ -33,6 +42,13 @@ describe('main', () => { expect(await page.textContent('.safe-fs-fetch-status')).toBe('200') }) + test('safe fs fetch with special characters', async () => { + expect(await page.textContent('.safe-fs-fetch-special-characters')).toBe( + stringified + ) + expect(await page.textContent('.safe-fs-fetch-status')).toBe('200') + }) + test('unsafe fs fetch', async () => { expect(await page.textContent('.unsafe-fs-fetch')).toBe('') expect(await page.textContent('.unsafe-fs-fetch-status')).toBe('403') diff --git a/packages/playground/fs-serve/root/src/index.html b/packages/playground/fs-serve/root/src/index.html index 9e4f728a593a91..951e14ad2cce91 100644 --- a/packages/playground/fs-serve/root/src/index.html +++ b/packages/playground/fs-serve/root/src/index.html @@ -11,6 +11,8 @@

Safe Fetch

Safe Fetch Subdirectory


 

+

+

 
 

Unsafe Fetch


@@ -19,6 +21,8 @@ 

Unsafe Fetch

Safe /@fs/ Fetch


 

+

+

 
 

Unsafe /@fs/ Fetch


@@ -56,6 +60,16 @@ 

Denied

text('.safe-fetch-subdir', JSON.stringify(data)) }) + // inside allowed dir, with special characters, safe fetch + fetch('/src/special%20characters%20%C3%A5%C3%A4%C3%B6/safe.txt') + .then((r) => { + text('.safe-fetch-subdir-special-characters-status', r.status) + return r.text() + }) + .then((data) => { + text('.safe-fetch-subdir-special-characters', JSON.stringify(data)) + }) + // outside of allowed dir, treated as unsafe fetch('/unsafe.txt') .then((r) => { @@ -92,6 +106,20 @@

Denied

console.error(e) }) + // not imported before, inside root with special characters, treated as safe + fetch( + '/@fs/' + + ROOT + + '/root/src/special%20characters%20%C3%A5%C3%A4%C3%B6/safe.json' + ) + .then((r) => { + text('.safe-fs-fetch-special-characters-status', r.status) + return r.json() + }) + .then((data) => { + text('.safe-fs-fetch-special-characters', JSON.stringify(data)) + }) + // .env, denied by default fetch('/@fs/' + ROOT + '/root/.env') .then((r) => { diff --git "a/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.json" "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.json" new file mode 100644 index 00000000000000..84f96593c10bad --- /dev/null +++ "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.json" @@ -0,0 +1,3 @@ +{ + "msg": "safe" +} diff --git "a/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.txt" "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.txt" new file mode 100644 index 00000000000000..3f3d0607101642 --- /dev/null +++ "b/packages/playground/fs-serve/root/src/special characters \303\245\303\244\303\266/safe.txt" @@ -0,0 +1 @@ +KEY=safe diff --git a/packages/vite/src/node/server/middlewares/static.ts b/packages/vite/src/node/server/middlewares/static.ts index a6623338783cc8..5fb4f7fad2e055 100644 --- a/packages/vite/src/node/server/middlewares/static.ts +++ b/packages/vite/src/node/server/middlewares/static.ts @@ -111,7 +111,7 @@ export function serveRawFsMiddleware( // Keep the named function. The name is visible in debug logs via `DEBUG=connect:dispatcher ...` return function viteServeRawFsMiddleware(req, res, next) { - let url = req.url! + let url = decodeURI(req.url!) // In some cases (e.g. linked monorepos) files outside of root will // reference assets that are also out of served root. In such cases // the paths are rewritten to `/@fs/` prefixed paths and must be served by