From 1b378ed5b9b5429ba949d0440f26b61926fc8bcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20Verg=C3=A9?= Date: Tue, 5 Jan 2021 09:56:08 +0100 Subject: [PATCH] quoted-strings: Fix explicit octal recognition PyYAML implements YAML spec version 1.1, not 1.2. Hence, values starting with `0o` are not considered as numbers: they are just strings, so they need quotes when `quoted-strings: {required: true}`. >>> import yaml >>> yaml.resolver.Resolver().resolve(yaml.nodes.ScalarNode, '100', (True, False)) 'tag:yaml.org,2002:int' >>> yaml.resolver.Resolver().resolve(yaml.nodes.ScalarNode, '0100', (True, False)) 'tag:yaml.org,2002:int' >>> yaml.resolver.Resolver().resolve(yaml.nodes.ScalarNode, '0o100', (True, False)) 'tag:yaml.org,2002:str' Let's try to prevent that. Fixes https://github.com/adrienverge/yamllint/issues/351. --- tests/rules/test_quoted_strings.py | 18 ++++++++++++++++++ yamllint/rules/quoted_strings.py | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/tests/rules/test_quoted_strings.py b/tests/rules/test_quoted_strings.py index 1ee86a1..79f36bc 100644 --- a/tests/rules/test_quoted_strings.py +++ b/tests/rules/test_quoted_strings.py @@ -436,3 +436,21 @@ class QuotedTestCase(RuleTestCase): '- foo bar\n' '- "foo bar"\n', conf, problem1=(3, 3), problem2=(7, 3), problem3=(11, 3)) + + def test_octal_values(self): + conf = 'quoted-strings: {required: true}\n' + + self.check('---\n' + '- 100\n' + '- 0100\n' + '- 0o100\n' + '- 777\n' + '- 0777\n' + '- 0o777\n' + '- 800\n' + '- 0800\n' + '- 0o800\n' + '- "0800"\n' + '- "0o800"\n', + conf, + problem1=(9, 3), problem2=(10, 3)) diff --git a/yamllint/rules/quoted_strings.py b/yamllint/rules/quoted_strings.py index 279cd6a..1ef18db 100644 --- a/yamllint/rules/quoted_strings.py +++ b/yamllint/rules/quoted_strings.py @@ -144,6 +144,17 @@ def VALIDATE(conf): DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str' +# https://stackoverflow.com/a/36514274 +yaml.resolver.Resolver.add_implicit_resolver( + 'tag:yaml.org,2002:int', + re.compile(r'''^(?:[-+]?0b[0-1_]+ + |[-+]?0o?[0-7_]+ + |[-+]?0[0-7_]+ + |[-+]?(?:0|[1-9][0-9_]*) + |[-+]?0x[0-9a-fA-F_]+ + |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X), + list('-+0123456789')) + def _quote_match(quote_type, token_style): return ((quote_type == 'any') or