diff --git a/tests/test_syntax_errors.py b/tests/test_syntax_errors.py index bd4ddd2..12d5780 100644 --- a/tests/test_syntax_errors.py +++ b/tests/test_syntax_errors.py @@ -92,3 +92,28 @@ class YamlLintTestCase(RuleTestCase): ' a:\n' ' set\n' '...\n', None) + + def test_invalid_char_last(self): + self.check('---\nkey: value\t\n', + None, problem=(2, 11)) + + def test_invalid_char_first(self): + self.check('---\n\tkey: value\n', + None, problem=(2, 1)) + + def test_invalid_char_on_second_line(self): + self.check('---\nfoo: bar\n\toutput: foo\n', + None, problem=(3, 1)) + + def test_invalid_chars(self): + # We expect to identify only the first syntax error as this kind of + # error is fatal (stops parsing) + self.check('---\nkey: \tfoo\tbar\n', + None, + problem=(2, 6)) + + def test_invalid_char_with_other_rule(self): + self.check('key: value\t\n', + None, + problem1=(1, 1, 'document-start'), + problem2=(1, 11)) diff --git a/yamllint/linter.py b/yamllint/linter.py index 83e792c..bcc99f1 100644 --- a/yamllint/linter.py +++ b/yamllint/linter.py @@ -186,6 +186,15 @@ def get_syntax_error(buffer): 'syntax error: ' + e.problem + ' (syntax)') problem.level = 'error' return problem + except yaml.reader.ReaderError as e: + # we need to convert position into line+column + line = buffer.count('\n', 0, e.position) + col = e.position - (buffer.rindex('\n', 0, e.position) if line else 1) + problem = LintProblem(line + 1, + col, + 'syntax error: ' + e.reason + ' (syntax)') + problem.level = 'error' + return problem def _run(buffer, conf, filepath): diff --git a/yamllint/parser.py b/yamllint/parser.py index de331f4..e6a74a3 100644 --- a/yamllint/parser.py +++ b/yamllint/parser.py @@ -121,9 +121,9 @@ def comments_between_tokens(token1, token2): def token_or_comment_generator(buffer): - yaml_loader = yaml.BaseLoader(buffer) try: + yaml_loader = yaml.BaseLoader(buffer) prev = None curr = yaml_loader.get_token() while curr is not None: @@ -139,7 +139,8 @@ def token_or_comment_generator(buffer): prev = curr curr = next - except yaml.scanner.ScannerError: + # errors like this are already analysed by get_syntax_error + except (yaml.scanner.ScannerError, yaml.reader.ReaderError): pass