Skip to content

Commit 24a61a3

Browse files
authored
fix(css): improve url escape characters handling (#20847)
1 parent 4e35c9d commit 24a61a3

File tree

2 files changed

+12
-3
lines changed

2 files changed

+12
-3
lines changed

packages/vite/src/node/__tests__/plugins/css.spec.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ describe('search css url function', () => {
5656
),
5757
).toBe(true)
5858
})
59+
60+
test('should capture the full url with escaped parentheses', () => {
61+
const css = 'background-image: url(public/awkward-name\\)2.png);'
62+
const match = cssUrlRE.exec(css)
63+
expect(match?.[1].trim()).toBe('public/awkward-name\\)2.png')
64+
})
5965
})
6066

6167
describe('css modules', () => {

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1896,7 +1896,7 @@ type CssUrlReplacer = (
18961896
) => string | false | Promise<string | false>
18971897
// https://drafts.csswg.org/css-syntax-3/#identifier-code-point
18981898
export const cssUrlRE =
1899-
/(?<!@import\s+)(?<=^|[^\w\-\u0080-\uffff])url\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/
1899+
/(?<!@import\s+)(?<=^|[^\w\-\u0080-\uffff])url\((\s*('[^']+'|"[^"]+")\s*|(?:\\.|[^'")\\])+)\)/
19001900
export const cssDataUriRE =
19011901
/(?<=^|[^\w\-\u0080-\uffff])data-uri\((\s*('[^']+'|"[^"]+")\s*|[^'")]+)\)/
19021902
export const importCssRE =
@@ -2049,14 +2049,17 @@ async function doUrlReplace(
20492049
if (skipUrlReplacer(unquotedUrl)) {
20502050
return matched
20512051
}
2052+
// Remove escape sequences to get the actual file name before resolving.
2053+
unquotedUrl = unquotedUrl.replace(/\\(\W)/g, '$1')
20522054

20532055
let newUrl = await replacer(unquotedUrl, rawUrl)
20542056
if (newUrl === false) {
20552057
return matched
20562058
}
20572059

2058-
// The new url might need wrapping even if the original did not have it, e.g. if a space was added during replacement
2059-
if (wrap === '' && newUrl !== encodeURI(newUrl)) {
2060+
// The new url might need wrapping even if the original did not have it, e.g.
2061+
// if a space was added during replacement or the URL contains ")"
2062+
if (wrap === '' && (newUrl !== encodeURI(newUrl) || newUrl.includes(')'))) {
20602063
wrap = '"'
20612064
}
20622065
// If wrapping in single quotes and newUrl also contains single quotes, switch to double quotes.

0 commit comments

Comments
 (0)