Fixes #847 - ignores selectors with invalid characters.
authorJakub Pawlowicz <contact@jakubpawlowicz.com>
Fri, 23 Dec 2016 17:05:17 +0000 (18:05 +0100)
committerJakub Pawlowicz <contact@jakubpawlowicz.com>
Fri, 23 Dec 2016 17:11:23 +0000 (18:11 +0100)
Why:

* Browsers won't apply such rules so neither should we.

History.md
lib/optimizer/tidy-rules.js
lib/tokenizer/tokenize.js
test/module-test.js
test/optimizer/basic-test.js
test/tokenizer/tokenize-test.js

index 378b51e..50747b1 100644 (file)
@@ -19,6 +19,7 @@
 * Fixed issue [#839](https://github.com/jakubpawlowicz/clean-css/issues/839) - allows URIs in import inlining rules.
 * Fixed issue [#840](https://github.com/jakubpawlowicz/clean-css/issues/840) - allows input source map as map object.
 * Fixed issue [#843](https://github.com/jakubpawlowicz/clean-css/issues/843) - regression in selector handling.
+* Fixed issue [#847](https://github.com/jakubpawlowicz/clean-css/issues/847) - regression in handling invalid selectors.
 
 [3.4.23 / 2016-12-17](https://github.com/jakubpawlowicz/clean-css/compare/v3.4.22...v3.4.23)
 ==================
index 296b757..61231c3 100644 (file)
@@ -4,16 +4,11 @@ var formatPosition = require('../utils/format-position');
 var RELATION_PATTERN = /[>\+~]/;
 var WHITESPACE_PATTERN = /\s/;
 
+var LESS_THAN = '<';
 var STAR_PLUS_HTML_HACK = '*+html ';
 var STAR_FIRST_CHILD_PLUS_HTML_HACK = '*:first-child+html ';
 
 function hasInvalidCharacters(value) {
-  return value.indexOf(Marker.SINGLE_QUOTE) > -1 || value.indexOf(Marker.DOUBLE_QUOTE) > -1 ?
-    hasInvalidCharactersWithQuotes(value) :
-    hasInvalidCharactersWithoutQuotes(value);
-}
-
-function hasInvalidCharactersWithQuotes(value) {
   var isEscaped;
   var isInvalid = false;
   var character;
@@ -27,7 +22,10 @@ function hasInvalidCharactersWithQuotes(value) {
       // continue as always
     } else if (character == Marker.SINGLE_QUOTE || character == Marker.DOUBLE_QUOTE) {
       isQuote = !isQuote;
-    } else if (character == Marker.CLOSE_BRACE && !isQuote) {
+    } else if (!isQuote && (character == Marker.CLOSE_BRACE || character == Marker.EXCLAMATION || character == LESS_THAN)) {
+      isInvalid = true;
+      break;
+    } else if (!isQuote && i === 0 && RELATION_PATTERN.test(character)) {
       isInvalid = true;
       break;
     }
@@ -38,10 +36,6 @@ function hasInvalidCharactersWithQuotes(value) {
   return isInvalid;
 }
 
-function hasInvalidCharactersWithoutQuotes(value) {
-  return value.indexOf(Marker.CLOSE_BRACE) > -1;
-}
-
 function removeWhitespace(value, beautify) {
   var stripped = [];
   var character;
index 6ecad7f..3f509f6 100644 (file)
@@ -395,6 +395,12 @@ function intoTokens(source, externalContext, internalContext, isNested) {
   if (seekingValue && buffer.length > 0) {
     serializedBuffer = buffer.join('').replace(TAIL_BROKEN_VALUE_PATTERN, '');
     propertyToken.push([Token.PROPERTY_VALUE, serializedBuffer, [originalMetadata(metadata, serializedBuffer, externalContext)]]);
+
+    buffer = [];
+  }
+
+  if (buffer.length > 0) {
+    externalContext.warnings.push('Invalid character(s) \'' + buffer.join('') + '\' at ' + formatPosition(metadata) + '. Ignoring.');
   }
 
   return allTokens;
index 4460c2b..40baf70 100644 (file)
@@ -111,8 +111,9 @@ vows.describe('module tests').addBatch({
       assert.isEmpty(minified.errors);
     },
     'should raise one warning': function (error, minified) {
-      assert.lengthOf(minified.warnings, 1);
+      assert.lengthOf(minified.warnings, 2);
       assert.equal(minified.warnings[0], 'Unexpected \'}\' at 1:16.');
+      assert.equal(minified.warnings[1], 'Invalid character(s) \'}\' at 1:16. Ignoring.');
     }
   },
   'warnings on unexpected body': {
index 4c9cd54..40d9d01 100644 (file)
@@ -104,6 +104,18 @@ vows.describe('simple optimizations')
       'no rule scope': [
         '{overflow:hidden}',
         ''
+      ],
+      'invalid characters #1': [
+        '<![CDATA[p.b{background:red}]]>',
+        ''
+      ],
+      'invalid characters #2': [
+        '<funky{background:red}',
+        ''
+      ],
+      'invalid characters #3 - relation at the beginning': [
+        '>.funky{background:red}',
+        ''
       ]
     }, { advanced: false })
   )
index bd92ab9..292a246 100644 (file)
@@ -3498,6 +3498,23 @@ vows.describe(tokenize)
       'logs them correctly': function (warnings) {
         assert.deepEqual(warnings, ['Missing \'}\' at one.css:1:15.']);
       }
+    },
+    'warnings - extra characters': {
+      'topic': function () {
+        var warnings = [];
+
+        tokenize('<![CDATA[p.b{background:red}]]>', {
+          inputSourceMapTracker: inputSourceMapTracker(),
+          options: {},
+          source: 'one.css',
+          warnings: warnings
+        });
+
+        return warnings;
+      },
+      'logs them correctly': function (warnings) {
+        assert.deepEqual(warnings, ['Invalid character(s) \']]>\' at one.css:1:28. Ignoring.']);
+      }
     }
   })
   .addBatch({