From: Jakub Pawlowicz Date: Wed, 1 Jun 2016 09:10:17 +0000 (+0200) Subject: Fixes #776 - edge case in quoted data URIs. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=fc3c372af7292e18e155505e38d0d0c207a9dc8d;p=clean-css.git Fixes #776 - edge case in quoted data URIs. Regardless of whether data URI is quoted or not the end of URI should always be fuzzy matched. --- diff --git a/History.md b/History.md index 07658eb5..1b57ee92 100644 --- a/History.md +++ b/History.md @@ -6,6 +6,7 @@ [3.4.15 / 2016-xx-xx](https://github.com/jakubpawlowicz/clean-css/compare/v3.4.14...3.4) ================== +* Fixed issue [#776](https://github.com/jakubpawlowicz/clean-css/issues/776) - edge case in quoted data URIs. * Fixed issue [#779](https://github.com/jakubpawlowicz/clean-css/issues/779) - merging `background-(position|size)`. * Fixed issue [#780](https://github.com/jakubpawlowicz/clean-css/issues/780) - space after inlined variables. diff --git a/lib/urls/reduce.js b/lib/urls/reduce.js index 54c4ee7a..8dcbab68 100644 --- a/lib/urls/reduce.js +++ b/lib/urls/reduce.js @@ -1,7 +1,9 @@ var URL_PREFIX = 'url('; var UPPERCASE_URL_PREFIX = 'URL('; var URL_SUFFIX = ')'; -var DATA_URI_PREFIX = 'data:'; + +var DATA_URI_PREFIX_PATTERN = /^\s*['"]?\s*data:/; +var DATA_URI_END_FUZZY_PATTERN = /^\)[\s\{\};]/; var IMPORT_URL_PREFIX = '@import'; var UPPERCASE_IMPORT_URL_PREFIX = '@IMPORT'; @@ -27,27 +29,29 @@ function byUrl(data, context, callback) { if (nextStart == -1 && nextStartUpperCase > -1) nextStart = nextStartUpperCase; + isDataURI = DATA_URI_PREFIX_PATTERN.test(data.substring(nextStart + URL_PREFIX.length)); - if (data[nextStart + URL_PREFIX.length] == '"') { - nextEnd = data.indexOf('"', nextStart + URL_PREFIX.length + 1); - } else if (data[nextStart + URL_PREFIX.length] == '\'') { - nextEnd = data.indexOf('\'', nextStart + URL_PREFIX.length + 1); - } else { - isDataURI = data.substring(nextStart + URL_PREFIX.length).trim().indexOf(DATA_URI_PREFIX) === 0; + if (isDataURI) { nextEnd = data.indexOf(URL_SUFFIX, nextStart); - if (isDataURI) { - // this is a fuzzy matching logic for unqoted data URIs - while (true) { - nextEndAhead = data.indexOf(URL_SUFFIX, nextEnd + 1); - // if it has whitespace, curly braces, or semicolon then we should be out of URL, - // otherwise keep iterating if it has not but content is not escaped, - // it has to be quoted so it will be captured by either of two clauses above - if (nextEndAhead == -1 || /[\s\{\};]/.test(data.substring(nextEnd, nextEndAhead))) - break; - - nextEnd = nextEndAhead; - } + // this is a fuzzy matching logic for unqoted data URIs + while (true) { + nextEndAhead = data.indexOf(URL_SUFFIX, nextEnd + 1); + // if it has whitespace, curly braces, or semicolon then we should be out of URL, + // otherwise keep iterating if it has not but content is not escaped, + // it has to be quoted so it will be captured by either of two clauses above + if (nextEndAhead == -1 || DATA_URI_END_FUZZY_PATTERN.test(data.substring(nextEnd, nextEndAhead))) + break; + + nextEnd = nextEndAhead; + } + } else { + if (data[nextStart + URL_PREFIX.length] == '"') { + nextEnd = data.indexOf('"', nextStart + URL_PREFIX.length + 1); + } else if (data[nextStart + URL_PREFIX.length] == '\'') { + nextEnd = data.indexOf('\'', nextStart + URL_PREFIX.length + 1); + } else { + nextEnd = data.indexOf(URL_SUFFIX, nextStart); } } diff --git a/test/text/urls-processor-test.js b/test/text/urls-processor-test.js index ff66f76f..04974ed7 100644 --- a/test/text/urls-processor-test.js +++ b/test/text/urls-processor-test.js @@ -85,6 +85,16 @@ vows.describe(UrlsProcessor) 'a{background:url(url)}div:not([test]){color:red}', 'a{background:__ESCAPED_URL_CLEAN_CSS0__}div:not([test]){color:red}', 'a{background:url(url)}div:not([test]){color:red}' + ], + 'data URI with single brackets': [ + 'a{background-image:url(\'data:image/svg+xml;charset=utf-8,\')}', + 'a{background-image:__ESCAPED_URL_CLEAN_CSS0__}', + 'a{background-image:url(\'data:image/svg+xml;charset=utf-8,\')}' + ], + 'data URI with double brackets': [ + 'a{background-image:url("data:image/svg+xml;charset=utf-8,")}', + 'a{background-image:__ESCAPED_URL_CLEAN_CSS0__}', + 'a{background-image:url("data:image/svg+xml;charset=utf-8,")}' ] }) )