diff --git a/packages/vite/src/node/plugins/html.ts b/packages/vite/src/node/plugins/html.ts index 537f58470a9cbd..7d44c91280f9b3 100644 --- a/packages/vite/src/node/plugins/html.ts +++ b/packages/vite/src/node/plugins/html.ts @@ -534,8 +534,11 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { const processedEncodedUrl = await processSrcSet( attr.value, async ({ url }) => { - const decodedUrl = decodeURI(url) - if (!isExcludedUrl(decodedUrl)) { + const decodedUrl = decodeURIIfPossible(url) + if ( + decodedUrl !== undefined && + !isExcludedUrl(decodedUrl) + ) { const result = await processAssetUrl(url) return result !== decodedUrl ? encodeURIPath(result) @@ -550,8 +553,10 @@ export function buildHtmlPlugin(config: ResolvedConfig): Plugin { })(), ) } else if (attr.type === 'src') { - const url = decodeURI(attr.value) - if (checkPublicFile(url, config)) { + const url = decodeURIIfPossible(attr.value) + if (url === undefined) { + // ignore it + } else if (checkPublicFile(url, config)) { overwriteAttrValue( s, attr.location, @@ -1580,3 +1585,12 @@ function serializeAttrs(attrs: HtmlTagDescriptor['attrs']): string { function incrementIndent(indent: string = '') { return `${indent}${indent[0] === '\t' ? '\t' : ' '}` } + +function decodeURIIfPossible(input: string): string | undefined { + try { + return decodeURI(input) + } catch { + // url is malformed, probably a interpolate syntax of template engines + return + } +}