Skip to content

Commit d90a9d7

Browse files
author
benholloway
committed
fix css url() encoding bug
1 parent c4739ff commit d90a9d7

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

lib/build/node-sass.js

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function encodeRelativeURL(startPath, uri) {
8686
var type = mime.lookup(fullPath);
8787
var contents = fs.readFileSync(fullPath);
8888
var base64 = new Buffer(contents).toString('base64');
89-
return 'url(data:' + type + ';base64,' + base64 + ')';
89+
return 'data:' + type + ';base64,' + base64;
9090
}
9191
// enqueue subdirectories that are not packages and are not in the root path
9292
else {
@@ -163,12 +163,35 @@ module.exports = function (bannerWidth, libraryPaths) {
163163
var sassDir = path.dirname(sassStart.source);
164164

165165
// allow multiple url() values in the declaration
166-
// the uri will be every second value (i % 2)
166+
// split by url statements and process the content
167+
// additional capture groups are needed to match quotations correctly
168+
// escaped quotations are not considered
167169
declaration.value = declaration.value
168-
.split(/url\s*\(\s*['"]?([^'"?#]*)[^)]*\)/g) // split by url statements
169-
.map(function (token, i) {
170-
return (i % 2) ? (encodeRelativeURL(sassDir, token) || ('url(' + token + ')')) : token;
171-
}).join('');
170+
.split(/(url\s*\(\s*)(['"]?)((?:(?!\2|\?|#]).)*(?:(?!\2).)*)(\2\s*\))/g)
171+
.map(eachSplitOrGroup)
172+
.join('');
173+
174+
/**
175+
* Encode the content portion of <code>url()</code> statements.
176+
* There are 4 capture groups in the split making every 5th unmatched.
177+
* @param {string} token A single split item
178+
* @param i The index of the item in the split
179+
* @returns {string} Every 3 or 5 items is an encoded url everything else is as is
180+
*/
181+
function eachSplitOrGroup(token, i) {
182+
183+
// the quoted or unquoted content of the url() statement
184+
if (i % 5 === 3) {
185+
186+
// remove query string or hash suffix
187+
var uri = token.split(/[?#]/g).shift();
188+
return encodeRelativeURL(sassDir, uri) || token;
189+
}
190+
// everything else, including parentheses and quotation (where present) and media statements
191+
else {
192+
return token;
193+
}
194+
}
172195
});
173196
});
174197
}

0 commit comments

Comments
 (0)