Skip to content

Commit 1bbff16

Browse files
authored
fix(build): use base64 for inline SVG if it contains both single and double quotes (#15271)
1 parent d9ae1b2 commit 1bbff16

8 files changed

+45
-1
lines changed

packages/vite/src/node/plugins/asset.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -415,14 +415,17 @@ export async function urlToBuiltUrl(
415415
)
416416
}
417417

418+
const nestedQuotesRE = /"[^"']*'[^"]*"|'[^'"]*"[^']*'/
419+
418420
// Inspired by https://github.com/iconify/iconify/blob/main/packages/utils/src/svg/url.ts
419421
function svgToDataURL(content: Buffer): string {
420422
const stringContent = content.toString()
421423
// If the SVG contains some text or HTML, any transformation is unsafe, and given that double quotes would then
422424
// need to be escaped, the gain to use a data URI would be ridiculous if not negative
423425
if (
424426
stringContent.includes('<text') ||
425-
stringContent.includes('<foreignObject')
427+
stringContent.includes('<foreignObject') ||
428+
nestedQuotesRE.test(stringContent)
426429
) {
427430
return `data:image/svg+xml;base64,${content.toString('base64')}`
428431
} else {

playground/data-uri/__tests__/data-uri.spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@ test('base64', async () => {
99
expect(await page.textContent('.base64')).toBe('hi')
1010
})
1111

12+
test('svg data uri minify', async () => {
13+
const sqdqs = await page.getByTestId('sqdqs').boundingBox()
14+
const sqsdqs = await page.getByTestId('sqsdqs').boundingBox()
15+
const dqsqs = await page.getByTestId('dqsqs').boundingBox()
16+
const dqssqs = await page.getByTestId('dqssqs').boundingBox()
17+
18+
expect(sqdqs.height).toBe(100)
19+
expect(sqsdqs.height).toBe(100)
20+
expect(dqsqs.height).toBe(100)
21+
expect(dqssqs.height).toBe(100)
22+
})
23+
1224
test.runIf(isBuild)('should compile away the import for build', async () => {
1325
const file = findAssetFile('index')
1426
expect(file).not.toMatch('import')
Loading
Loading

playground/data-uri/index.html

+7
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@
1212
document.querySelector(el).textContent = text
1313
}
1414
</script>
15+
16+
<script type="module" src="./main.js"></script>
17+
18+
<div id="sqdqs"></div>
19+
<div id="sqsdqs"></div>
20+
<div id="dqsqs"></div>
21+
<div id="dqssqs"></div>

playground/data-uri/main.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import sqdqs from './single-quote-in-double-quotes.svg'
2+
import sqsdqs from './single-quotes-in-double-quotes.svg'
3+
import dqsqs from './double-quote-in-single-quotes.svg'
4+
import dqssqs from './double-quotes-in-single-quotes.svg'
5+
6+
document.querySelector('#sqdqs').innerHTML = `
7+
<img data-testid="sqdqs" src="${sqdqs}" class="sqdqs" alt="load failed" />
8+
`
9+
document.querySelector('#sqsdqs').innerHTML = `
10+
<img data-testid="sqsdqs" src="${sqsdqs}" class="sqsdqs" alt="load failed" />
11+
`
12+
13+
document.querySelector('#dqsqs').innerHTML = `
14+
<img data-testid="dqsqs" src="${dqsqs}" class="dqsqs" alt="load failed" />
15+
`
16+
document.querySelector('#dqssqs').innerHTML = `
17+
<img data-testid="dqssqs" src="${dqssqs}" class="dqssqs" alt="load failed" />
18+
`
Loading
Loading

0 commit comments

Comments
 (0)