From 512fe17047d68f55a885f628f65e005a47b827f4 Mon Sep 17 00:00:00 2001 From: Brad Solomon Date: Thu, 30 Apr 2020 10:38:19 -0400 Subject: [PATCH] Fix bug with CRLF in new-lines and require-starting-space Pound-signs followed by a lone CRLF should not raise if require-starting-space is specified. If require-starting-space is true, *and* either: - new-lines: disbale, or - newlines: type: dos is specified, a line with `#\r` or `#\r\n` should not raise a false positive. This commit also uses a Set for O(1) membership testing and uses the correct escape sequence for the nul byte. If we find a CRLF when looking for Unix newlines, yamllint should always raise, regardless of logic with require-starting-space. Closes: Issue #171. --- tests/rules/test_comments.py | 21 +++++++++++++++++++++ tests/rules/test_new_lines.py | 10 ++++++++++ yamllint/rules/comments.py | 4 +++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/rules/test_comments.py b/tests/rules/test_comments.py index ad18a0e..2c3f399 100644 --- a/tests/rules/test_comments.py +++ b/tests/rules/test_comments.py @@ -186,6 +186,27 @@ class CommentsTestCase(RuleTestCase): 'inline: comment #\n' 'foo: bar\n', conf) + def test_empty_comment_crlf_dos_newlines(self): + conf = ('comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + 'new-lines:\n' + ' type: dos\n') + self.check('---\r\n' + '# This is paragraph 1.\r\n' + '#\r\n' + '# This is paragraph 2.\r\n', conf) + + def test_empty_comment_crlf_disabled_newlines(self): + conf = ('comments:\n' + ' require-starting-space: true\n' + ' min-spaces-from-content: 2\n' + 'new-lines: disable\n') + self.check('---\r\n' + '# This is paragraph 1.\r\n' + '#\r\n' + '# This is paragraph 2.\r\n', conf) + def test_first_line(self): conf = ('comments:\n' ' require-starting-space: true\n' diff --git a/tests/rules/test_new_lines.py b/tests/rules/test_new_lines.py index a76d608..23f2957 100644 --- a/tests/rules/test_new_lines.py +++ b/tests/rules/test_new_lines.py @@ -40,6 +40,16 @@ class NewLinesTestCase(RuleTestCase): self.check('---\ntext\n', conf) self.check('---\r\ntext\r\n', conf, problem=(1, 4)) + def test_unix_type_required_st_sp(self): + # If we find a CRLF when looking for Unix newlines, yamllint + # should always raise, regardless of logic with + # require-starting-space. + conf = ('new-line-at-end-of-file: disable\n' + 'new-lines: {type: unix}\n' + 'comments:\n' + ' require-starting-space: true\n') + self.check('---\r\n#\r\n', conf, problem=(1, 4)) + def test_dos_type(self): conf = ('new-line-at-end-of-file: disable\n' 'new-lines: {type: dos}\n') diff --git a/yamllint/rules/comments.py b/yamllint/rules/comments.py index 0122838..1e81db5 100644 --- a/yamllint/rules/comments.py +++ b/yamllint/rules/comments.py @@ -97,7 +97,9 @@ def check(conf, comment): comment.column_no == 1 and re.match(r'^!\S', comment.buffer[text_start:])): return - elif comment.buffer[text_start] not in (' ', '\n', '\0'): + # We can test for both \r and \r\n just by checking first char + # \r itself is a valid newline on some older OS. + elif comment.buffer[text_start] not in {' ', '\n', '\r', '\x00'}: column = comment.column_no + text_start - comment.pointer yield LintProblem(comment.line_no, column,