From: Jakub Pawlowicz Date: Fri, 5 Dec 2014 23:10:52 +0000 (+0000) Subject: Fixes #395 - unescaped brackets in data URIs. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=4e80090a7cdf52e586a66c839d2a965ef868de02;p=clean-css.git Fixes #395 - unescaped brackets in data URIs. --- diff --git a/History.md b/History.md index 28b2e06e..1e13e145 100644 --- a/History.md +++ b/History.md @@ -16,6 +16,7 @@ * Fixed issue [#344](https://github.com/GoalSmashers/clean-css/issues/344) - merging background-size into shorthand. * Fixed issue [#360](https://github.com/GoalSmashers/clean-css/issues/360) - adds 7 extra CSS colors. * Fixed issue [#363](https://github.com/GoalSmashers/clean-css/issues/363) - `rem` units overriding `px`. +* Fixed issue [#395](https://github.com/GoalSmashers/clean-css/issues/395) - unescaped brackets in data URIs. [2.2.19 / 2014-11-20](https://github.com/jakubpawlowicz/clean-css/compare/v2.2.18...v2.2.19) ================== diff --git a/lib/text/urls-processor.js b/lib/text/urls-processor.js index 8554dc77..3c49c312 100644 --- a/lib/text/urls-processor.js +++ b/lib/text/urls-processor.js @@ -1,5 +1,8 @@ var EscapeStore = require('./escape-store'); +var URL_PREFIX = 'url('; +var URL_SUFFIX = ')'; + var UrlsProcessor = function UrlsProcessor(context) { this.urls = new EscapeStore('URL'); this.context = context; @@ -15,11 +18,17 @@ UrlsProcessor.prototype.escape = function (data) { var tempData = []; for (; nextEnd < data.length;) { - nextStart = data.indexOf('url(', nextEnd); + nextStart = data.indexOf(URL_PREFIX, nextEnd); if (nextStart == -1) break; - nextEnd = data.indexOf(')', nextStart); + 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); + // Following lines are a safety mechanism to ensure // incorrectly terminated urls are processed correctly. if (nextEnd == -1) { @@ -31,6 +40,9 @@ UrlsProcessor.prototype.escape = function (data) { nextEnd--; this.context.warnings.push('Broken URL declaration: \'' + data.substring(nextStart, nextEnd + 1) + '\'.'); + } else { + if (data[nextEnd] != URL_SUFFIX) + nextEnd = data.indexOf(URL_SUFFIX, nextEnd); } var url = data.substring(nextStart, nextEnd + 1); @@ -53,7 +65,7 @@ function normalize(url) { .replace(/^url\((['"])? /, 'url($1') .replace(/ (['"])?\)$/, '$1)'); - if (url.indexOf(' ') == -1 && !/url\(['"]data:[^;]+;charset/.test(url)) + if (!/url\(.*[\s\(\)].*\)/.test(url) && !/url\(['"]data:[^;]+;charset/.test(url)) url = url.replace(/["']/g, ''); return url; diff --git a/test/data/issue-395-min.css b/test/data/issue-395-min.css new file mode 100644 index 00000000..53ad7800 --- /dev/null +++ b/test/data/issue-395-min.css @@ -0,0 +1 @@ +div{background:url("data:image/svg+xml,%3Csvg viewBox%3D%270 0 40 40%27 height%3D%2725%27 width%3D%2725%27%0Axmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3Cpath fill%3D%27rgb(91%2C 183%2C 91)%27 d%3D%27M2.379%2C%0A14.729L5.208%2C11.899L12.958%2C19.648L25.877%2C6.733L28.707%2C9.561L12.958%2C25.308Z%27%0A%2F%3E%3C%2Fsvg%3E")} diff --git a/test/data/issue-395.css b/test/data/issue-395.css new file mode 100644 index 00000000..b259c9a0 --- /dev/null +++ b/test/data/issue-395.css @@ -0,0 +1,3 @@ +div { + background: url("data:image/svg+xml,%3Csvg viewBox%3D%270 0 40 40%27 height%3D%2725%27 width%3D%2725%27%0Axmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%3E%3Cpath fill%3D%27rgb(91%2C 183%2C 91)%27 d%3D%27M2.379%2C%0A14.729L5.208%2C11.899L12.958%2C19.648L25.877%2C6.733L28.707%2C9.561L12.958%2C25.308Z%27%0A%2F%3E%3C%2Fsvg%3E") +} diff --git a/test/text/urls-processor-test.js b/test/text/urls-processor-test.js index f742b2f9..893cb213 100644 --- a/test/text/urls-processor-test.js +++ b/test/text/urls-processor-test.js @@ -73,6 +73,11 @@ vows.describe(UrlsProcessor) 'div{background:url(\' some/\nfile.png \') repeat}', 'div{background:__ESCAPED_URL_CLEAN_CSS0__ repeat}', 'div{background:url(some/file.png) repeat}' + ], + 'unescaped closing brackets': [ + 'div{background:url("some/).png") repeat}', + 'div{background:__ESCAPED_URL_CLEAN_CSS0__ repeat}', + 'div{background:url("some/).png") repeat}' ] }) )