Skip to content

Commit

Permalink
Fix: escape double quote of url value in CSS url() (#7718)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shinyaigeek committed Mar 20, 2022
1 parent 5412f65 commit 7d2c1ef
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 3 deletions.
12 changes: 12 additions & 0 deletions packages/core/integration-tests/test/css.js
Expand Up @@ -244,6 +244,18 @@ describe('css', () => {
);
});

it('should handle quote in CSS URL correctly', async function () {
await bundle(path.join(__dirname, '/integration/css-url-quote/index.css'));

let css = await outputFS.readFile(path.join(distDir, 'index.css'), 'utf8');

assert(
css.includes(
'url("data:image/svg+xml;utf8,with quote \\" and escape \\\\");',
),
);
});

it('should ignore url() with IE behavior specifiers', async function () {
let b = await bundle(
path.join(__dirname, '/integration/css-url-behavior/index.css'),
Expand Down
@@ -0,0 +1,5 @@
.quotes {
background-image: url('data:image/svg+xml;utf8,with quote " and escape \\');
width: 100px;
height: 100px;
}
@@ -0,0 +1,5 @@
require('./index.css');

module.exports = function () {
return 2;
};
10 changes: 8 additions & 2 deletions packages/core/utils/src/replaceBundleReferences.js
Expand Up @@ -33,13 +33,15 @@ export function replaceURLReferences({
bundleGraph,
contents,
map,
getReplacement = s => s,
relative = true,
}: {|
bundle: NamedBundle,
bundleGraph: BundleGraph<NamedBundle>,
contents: string,
relative?: boolean,
map?: ?SourceMap,
getReplacement?: string => string,
|}): {|+contents: string, +map: ?SourceMap|} {
let replacements = new Map();
let urlDependencies = [];
Expand All @@ -61,7 +63,7 @@ export function replaceURLReferences({
if (resolved == null) {
replacements.set(placeholder, {
from: placeholder,
to: dependency.specifier,
to: getReplacement(dependency.specifier),
});
continue;
}
Expand All @@ -79,6 +81,7 @@ export function replaceURLReferences({
fromBundle: bundle,
toBundle: resolved,
relative,
getReplacement,
}),
);
}
Expand Down Expand Up @@ -156,11 +159,13 @@ export function getURLReplacement({
fromBundle,
toBundle,
relative,
getReplacement,
}: {|
dependency: Dependency,
fromBundle: NamedBundle,
toBundle: NamedBundle,
relative: boolean,
getReplacement?: string => string,
|}): {|from: string, to: string|} {
let to;
Expand Down Expand Up @@ -191,9 +196,10 @@ export function getURLReplacement({

let placeholder = dependency.meta?.placeholder ?? dependency.id;
invariant(typeof placeholder === 'string');

return {
from: placeholder,
to,
to: getReplacement ? getReplacement(to) : to,
};
}

Expand Down
7 changes: 6 additions & 1 deletion packages/packagers/css/src/CSSPackager.js
Expand Up @@ -129,6 +129,7 @@ export default (new Packager({
bundleGraph,
contents,
map,
getReplacement: escapeString,
}));

return replaceInlineReferences({
Expand All @@ -138,7 +139,7 @@ export default (new Packager({
getInlineBundleContents,
getInlineReplacement: (dep, inlineType, contents) => ({
from: getSpecifier(dep),
to: contents,
to: escapeString(contents),
}),
map,
});
Expand All @@ -153,6 +154,10 @@ export function getSpecifier(dep: Dependency): string {
return dep.id;
}

function escapeString(contents: string): string {
return contents.replace(/(["\\])/g, '\\$1');
}

async function processCSSModule(
options,
logger,
Expand Down
1 change: 1 addition & 0 deletions packages/packagers/html/src/HTMLPackager.js
Expand Up @@ -74,6 +74,7 @@ export default (new Packager({
bundleGraph,
contents: html,
relative: false,
getReplacement: contents => contents.replace(/"/g, '&quot;'),
});

return replaceInlineReferences({
Expand Down
1 change: 1 addition & 0 deletions packages/packagers/js/src/index.js
Expand Up @@ -72,6 +72,7 @@ export default (new Packager({
bundleGraph,
contents,
map,
getReplacement: s => JSON.stringify(s).slice(1, -1),
}));
}

Expand Down
1 change: 1 addition & 0 deletions packages/packagers/raw-url/src/RawUrlPackager.js
Expand Up @@ -17,6 +17,7 @@ export default (new Packager({
bundleGraph,
contents: await assets[0].getCode(),
relative: false,
getReplacement: s => s,
});
return {contents};
},
Expand Down
1 change: 1 addition & 0 deletions packages/packagers/svg/src/SVGPackager.js
Expand Up @@ -58,6 +58,7 @@ export default (new Packager({
bundleGraph,
contents: svg,
relative: false,
getReplacement: contents => contents.replace(/"/g, '&quot;'),
});

return replaceInlineReferences({
Expand Down
1 change: 1 addition & 0 deletions packages/packagers/xml/src/XMLPackager.js
Expand Up @@ -68,6 +68,7 @@ export default (new Packager({
bundleGraph,
contents: code,
relative: false,
getReplacement: contents => contents.replace(/"/g, '&quot;'),
});

return replaceInlineReferences({
Expand Down

0 comments on commit 7d2c1ef

Please sign in to comment.