diff --git a/History.md b/History.md index 6d43df3cd..0cd817017 100644 --- a/History.md +++ b/History.md @@ -3,6 +3,7 @@ * Fixed issue [#959](https://github.com/jakubpawlowicz/clean-css/issues/959) - regression in shortening long hex values. * Fixed issue [#960](https://github.com/jakubpawlowicz/clean-css/issues/960) - better explanation of `efficiency` stat. +* Fixed issue [#965](https://github.com/jakubpawlowicz/clean-css/issues/965) - edge case in parsing comment endings. [4.1.7 / 2017-07-14](https://github.com/jakubpawlowicz/clean-css/compare/v4.1.6...v4.1.7) ================== diff --git a/lib/tokenizer/tokenize.js b/lib/tokenizer/tokenize.js index 018b89de8..c20e0b39b 100644 --- a/lib/tokenizer/tokenize.js +++ b/lib/tokenizer/tokenize.js @@ -97,6 +97,7 @@ function intoTokens(source, externalContext, internalContext, isNested) { var wasCommentStart = false; var isCommentEnd; var wasCommentEnd = false; + var isCommentEndMarker; var isEscaped; var wasEscaped = false; var seekingValue = false; @@ -111,7 +112,8 @@ function intoTokens(source, externalContext, internalContext, isNested) { isNewLineNix = character == Marker.NEW_LINE_NIX; isNewLineWin = character == Marker.NEW_LINE_NIX && source[position.index - 1] == Marker.NEW_LINE_WIN; isCommentStart = !wasCommentEnd && level != Level.COMMENT && !isQuoted && character == Marker.ASTERISK && source[position.index - 1] == Marker.FORWARD_SLASH; - isCommentEnd = !wasCommentStart && level == Level.COMMENT && character == Marker.FORWARD_SLASH && source[position.index - 1] == Marker.ASTERISK; + isCommentEndMarker = !wasCommentStart && !isQuoted && character == Marker.FORWARD_SLASH && source[position.index - 1] == Marker.ASTERISK; + isCommentEnd = level == Level.COMMENT && isCommentEndMarker; metadata = buffer.length === 0 ? [position.line, position.column, position.source] : @@ -147,6 +149,9 @@ function intoTokens(source, externalContext, internalContext, isNested) { level = levels.pop(); metadata = metadatas.pop() || null; buffer = buffers.pop() || []; + } else if (isCommentEndMarker && source[position.index + 1] != Marker.ASTERISK) { + externalContext.warnings.push('Unexpected \'*/\' at ' + formatPosition([position.line, position.column, position.source]) + '.'); + buffer = []; } else if (character == Marker.SINGLE_QUOTE && !isQuoted) { // single quotation start, e.g. a[href^='https<-- levels.push(level); diff --git a/test/tokenizer/tokenize-test.js b/test/tokenizer/tokenize-test.js index fdef4354c..bb752b61b 100644 --- a/test/tokenizer/tokenize-test.js +++ b/test/tokenizer/tokenize-test.js @@ -1015,6 +1015,80 @@ vows.describe(tokenize) ] ] ], + 'two comments one inside another and two rules': [ + '.block-1{color:red;/* comment 1 /* comment 2 */ */}.block-2{color:blue}', + [ + [ + 'rule', + [ + [ + 'rule-scope', + '.block-1', + [ + [1, 0, undefined] + ] + ] + ], + [ + [ + 'property', + [ + 'property-name', + 'color', + [ + [1, 9, undefined] + ] + ], + [ + 'property-value', + 'red', + [ + [1, 15, undefined] + ] + ] + ], + [ + 'comment', + '/* comment 1 /* comment 2 */', + [ + [1, 19, undefined] + ] + ] + ] + ], + [ + 'rule', + [ + [ + 'rule-scope', + '.block-2', + [ + [1, 51, undefined] + ] + ] + ], + [ + [ + 'property', + [ + 'property-name', + 'color', + [ + [1, 60, undefined] + ] + ], + [ + 'property-value', + 'blue', + [ + [1, 66, undefined] + ] + ] + ] + ] + ] + ] + ], 'rule wrapped between comments': [ '/* comment 1 */div/* comment 2 */{color:red}', [