Skip to content

Commit 48808f7

Browse files
Fixes #1000 - carriage return handling in tokenizer.
1 parent ec259be commit 48808f7

5 files changed

Lines changed: 21 additions & 6 deletions

File tree

History.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Fixed issue [#895](https://github.com/jakubpawlowicz/clean-css/issues/895) - ignoring specific styles.
77
* Fixed issue [#947](https://github.com/jakubpawlowicz/clean-css/issues/947) - selector based filtering.
88
* Fixed issue [#986](https://github.com/jakubpawlowicz/clean-css/issues/986) - level 2 optimizations and CSS 4 colors.
9+
* Fixed issue [#1000](https://github.com/jakubpawlowicz/clean-css/issues/1000) - carriage return handling in tokenizer.
910
* Fixed issue [#1038](https://github.com/jakubpawlowicz/clean-css/issues/1038) - `font-variation-settings` quoting.
1011
* Fixes ReDOS vulnerabilities in validator code.
1112

lib/optimizer/level-1/tidy-rules.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function removeWhitespace(value, format) {
6868
character = value[i];
6969

7070
isNewLineNix = character == Marker.NEW_LINE_NIX;
71-
isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.NEW_LINE_WIN;
71+
isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.CARRIAGE_RETURN;
7272
isQuoted = isSingleQuoted || isDoubleQuoted;
7373
isRelation = !isAttribute && !isEscaped && roundBracketLevel === 0 && RELATION_PATTERN.test(character);
7474
isWhitespace = WHITESPACE_PATTERN.test(character);

lib/tokenizer/marker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ var Marker = {
22
ASTERISK: '*',
33
AT: '@',
44
BACK_SLASH: '\\',
5+
CARRIAGE_RETURN: '\r',
56
CLOSE_CURLY_BRACKET: '}',
67
CLOSE_ROUND_BRACKET: ')',
78
CLOSE_SQUARE_BRACKET: ']',
@@ -12,7 +13,6 @@ var Marker = {
1213
FORWARD_SLASH: '/',
1314
INTERNAL: '-clean-css-',
1415
NEW_LINE_NIX: '\n',
15-
NEW_LINE_WIN: '\r',
1616
OPEN_CURLY_BRACKET: '{',
1717
OPEN_ROUND_BRACKET: '(',
1818
OPEN_SQUARE_BRACKET: '[',

lib/tokenizer/tokenize.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ function intoTokens(source, externalContext, internalContext, isNested) {
9797
var isSpace;
9898
var isNewLineNix;
9999
var isNewLineWin;
100+
var isCarriageReturn;
100101
var isCommentStart;
101102
var wasCommentStart = false;
102103
var isCommentEnd;
@@ -116,7 +117,8 @@ function intoTokens(source, externalContext, internalContext, isNested) {
116117
isQuoted = level == Level.SINGLE_QUOTE || level == Level.DOUBLE_QUOTE;
117118
isSpace = character == Marker.SPACE || character == Marker.TAB;
118119
isNewLineNix = character == Marker.NEW_LINE_NIX;
119-
isNewLineWin = character == Marker.NEW_LINE_NIX && source[position.index - 1] == Marker.NEW_LINE_WIN;
120+
isNewLineWin = character == Marker.NEW_LINE_NIX && source[position.index - 1] == Marker.CARRIAGE_RETURN;
121+
isCarriageReturn = character == Marker.CARRIAGE_RETURN && source[position.index + 1] && source[position.index + 1] != Marker.NEW_LINE_NIX;
120122
isCommentStart = !wasCommentEnd && level != Level.COMMENT && !isQuoted && character == Marker.ASTERISK && source[position.index - 1] == Marker.FORWARD_SLASH;
121123
isCommentEndMarker = !wasCommentStart && !isQuoted && character == Marker.FORWARD_SLASH && source[position.index - 1] == Marker.ASTERISK;
122124
isCommentEnd = level == Level.COMMENT && isCommentEndMarker;
@@ -483,7 +485,7 @@ function intoTokens(source, externalContext, internalContext, isNested) {
483485
} else if (buffer.length == 1 && isNewLineWin) {
484486
// ignore windows newline which is composed of two characters
485487
buffer.pop();
486-
} else if (buffer.length > 0 || !isSpace && !isNewLineNix && !isNewLineWin) {
488+
} else if (buffer.length > 0 || !isSpace && !isNewLineNix && !isNewLineWin && !isCarriageReturn) {
487489
// any character
488490
buffer.push(character);
489491
}
@@ -493,8 +495,8 @@ function intoTokens(source, externalContext, internalContext, isNested) {
493495
wasCommentStart = isCommentStart;
494496
wasCommentEnd = isCommentEnd;
495497

496-
position.line = (isNewLineWin || isNewLineNix) ? position.line + 1 : position.line;
497-
position.column = (isNewLineWin || isNewLineNix) ? 0 : position.column + 1;
498+
position.line = (isNewLineWin || isNewLineNix || isCarriageReturn) ? position.line + 1 : position.line;
499+
position.column = (isNewLineWin || isNewLineNix || isCarriageReturn) ? 0 : position.column + 1;
498500
}
499501

500502
if (seekingValue) {

test/tokenizer/tokenize-test.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2688,6 +2688,18 @@ vows.describe(tokenize)
26882688
]
26892689
]
26902690
],
2691+
'charset after a carriage return': [
2692+
'\r@charset \n\'utf-8\';',
2693+
[
2694+
[
2695+
'at-rule',
2696+
'@charset \n\'utf-8\'',
2697+
[
2698+
[2, 0, undefined]
2699+
]
2700+
]
2701+
]
2702+
],
26912703
'@import': [
26922704
'a{}@import \n"test.css";\n\na{color:red}',
26932705
[

0 commit comments

Comments
 (0)