From 730afc64e28682e4cf6963c5eaa22bd664eb51d0 Mon Sep 17 00:00:00 2001 From: vaibhavmashal Date: Mon, 24 Aug 2026 01:38:53 +0530 Subject: [PATCH] fix(asset): preserve IPv6 brackets in server origin for ?url imports --- packages/vite/src/node/__tests__/utils.spec.ts | 14 ++++++++++++++ packages/vite/src/node/utils.ts | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/vite/src/node/__tests__/utils.spec.ts b/packages/vite/src/node/__tests__/utils.spec.ts index 7974ab754301da..c9041612345fd3 100644 --- a/packages/vite/src/node/__tests__/utils.spec.ts +++ b/packages/vite/src/node/__tests__/utils.spec.ts @@ -18,6 +18,7 @@ import { getHash, getLocalhostAddressIfDiffersFromDNS, getServerUrlByHost, + encodeURIPath, injectQuery, isFileReadable, isParentDirectory, @@ -1257,3 +1258,16 @@ describe('resolveServerUrls', () => { expect(result.networkInterfaceNames).toStrictEqual([undefined]) }) }) + + +describe('encodeURIPath', () => { + test('encodes path correctly', () => { + expect(encodeURIPath('/foo/bar.txt')).toBe('/foo/bar.txt') + expect(encodeURIPath('/foo/[bar].txt')).toBe('/foo/%5Bbar%5D.txt') + }) + + test('does not encode IPv6 brackets in host', () => { + expect(encodeURIPath('http://[::1]:5173/foo/bar.txt')).toBe('http://[::1]:5173/foo/bar.txt') + expect(encodeURIPath('http://[::1]:5173/foo/[bar].txt')).toBe('http://[::1]:5173/foo/%5Bbar%5D.txt') + }) +}) diff --git a/packages/vite/src/node/utils.ts b/packages/vite/src/node/utils.ts index a501e50eda397b..e2a1dd903f7d81 100644 --- a/packages/vite/src/node/utils.ts +++ b/packages/vite/src/node/utils.ts @@ -1888,7 +1888,12 @@ export function encodeURIPath(uri: string): string { if (uri.startsWith('data:')) return uri const filePath = cleanUrl(uri) const postfix = filePath !== uri ? uri.slice(filePath.length) : '' - return encodeURI(filePath) + postfix + const encoded = encodeURI(filePath) + return ( + encoded.replace(/^([a-zA-Z]+:\/\/[^/]+)/, (match) => + match.replace(/%5B/g, '[').replace(/%5D/g, ']'), + ) + postfix + ) } /**