Skip to content

Commit

Permalink
fix: handling unquoted syntax url with escaped characters (#1010)
Browse files Browse the repository at this point in the history
  • Loading branch information
evilebottnawi committed Dec 10, 2019
1 parent 880344b commit b119d02
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 14 deletions.
36 changes: 25 additions & 11 deletions src/plugins/postcss-url-parser.js
Expand Up @@ -11,20 +11,20 @@ function getNodeFromUrlFunc(node) {
return node.nodes && node.nodes[0];
}

function getUrlFromUrlFunc(node) {
return node.nodes.length !== 0 && node.nodes[0].type === 'string'
? node.nodes[0].value
: valueParser.stringify(node.nodes);
}

function walkUrls(parsed, callback) {
parsed.walk((node) => {
if (node.type !== 'function') {
return;
}

if (isUrlFunc.test(node.value)) {
callback(getNodeFromUrlFunc(node), getUrlFromUrlFunc(node), false);
const isStringNode =
node.nodes.length !== 0 && node.nodes[0].type === 'string';
const url = isStringNode
? node.nodes[0].value
: valueParser.stringify(node.nodes);

callback(getNodeFromUrlFunc(node), url, false, isStringNode);

// Do not traverse inside `url`
// eslint-disable-next-line consistent-return
Expand All @@ -34,11 +34,17 @@ function walkUrls(parsed, callback) {
if (isImageSetFunc.test(node.value)) {
node.nodes.forEach((nNode) => {
if (nNode.type === 'function' && isUrlFunc.test(nNode.value)) {
callback(getNodeFromUrlFunc(nNode), getUrlFromUrlFunc(nNode), false);
const isStringNode =
nNode.nodes.length !== 0 && nNode.nodes[0].type === 'string';
const url = isStringNode
? nNode.nodes[0].value
: valueParser.stringify(nNode.nodes);

callback(getNodeFromUrlFunc(nNode), url, false, isStringNode);
}

if (nNode.type === 'string') {
callback(nNode, nNode.value, true);
callback(nNode, nNode.value, true, true);
}
});

Expand All @@ -57,7 +63,7 @@ function getUrlsFromValue(value, result, filter, decl) {
const parsed = valueParser(value);
const urls = [];

walkUrls(parsed, (node, url, needQuotes) => {
walkUrls(parsed, (node, url, needQuotes, isStringNode) => {
if (url.trim().replace(/\\[\r\n]/g, '').length === 0) {
result.warn(`Unable to find uri in '${decl ? decl.toString() : value}'`, {
node: decl,
Expand All @@ -70,12 +76,20 @@ function getUrlsFromValue(value, result, filter, decl) {
return;
}

const [normalizedUrl, singleQuery, hashValue] = url.split(/(\?)?#/);
const splittedUrl = url.split(/(\?)?#/);
let [normalizedUrl] = splittedUrl;
const [, singleQuery, hashValue] = splittedUrl;
const hash =
singleQuery || hashValue
? `${singleQuery ? '?' : ''}${hashValue ? `#${hashValue}` : ''}`
: '';

// Remove extra escaping requirements for `require`
// See https://drafts.csswg.org/css-values-3/#urls
if (!isStringNode && /\\["'() \t\n]/.test(normalizedUrl)) {
normalizedUrl = normalizedUrl.replace(/\\(["'() \t\n])/g, '$1');
}

urls.push({ node, url: normalizedUrl, hash, needQuotes });
});

Expand Down
85 changes: 82 additions & 3 deletions test/__snapshots__/url-option.test.js.snap

Large diffs are not rendered by default.

Binary file added test/fixtures/url/img'''img.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/url/img'() img.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/url/img'img.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/url/img(img.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/fixtures/url/img)img.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions test/fixtures/url/url.css
Expand Up @@ -268,3 +268,26 @@ a {

background-image: image-set(url("./img1x.png") 1x, "./img2x.png" 2x);
}

.class {
/* Not allowed on windows */
/* background: url(./img\"img.png); */
background: url(./img\'img.png);
background: url(./img\'\'\'img.png);
background: url(./img\(img.png);
background: url(./img\)img.png);
background: url(./img\ img.png);
background: url(./img\'\(\)\ img.png);

background-image: image-set(
/* Not allowed on windows */
/* url(./img\"img.png) 1x, */
url(./img\'\'\'img.png) 2x,
url(./img\'img.png) 3x,
url(./img\(img.png) 4x,
url(./img\)img.png) 5x,
url(./img\ img.png) 6x,
url(./img\'\(\)\ img.png) 7x
);
}

0 comments on commit b119d02

Please sign in to comment.