diff options
author | Brian Coca <bcoca@users.noreply.github.com> | 2020-11-10 10:48:20 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-11-10 10:48:20 -0500 |
commit | 48c08f410cd368b129fed61f9a58a0cc2b1df458 (patch) | |
tree | fa0d449e647f415c0d4a01fd38a33826d8864c5c | |
parent | e879f12fb9629842f6c9c1a18ebd9dfd3e23de32 (diff) | |
download | ansible-48c08f410cd368b129fed61f9a58a0cc2b1df458.tar.gz |
allow any type of unsafe data (#72547)
* allow any type of unsafe data
dont limit to strings
-rw-r--r-- | changelogs/fragments/unsafe_for_all.yml | 2 | ||||
-rw-r--r-- | lib/ansible/parsing/yaml/constructor.py | 16 | ||||
-rw-r--r-- | test/integration/targets/yaml_parsing/tasks/main.yml | 4 | ||||
-rw-r--r-- | test/integration/targets/yaml_parsing/tasks/unsafe.yml | 36 | ||||
-rw-r--r-- | test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py | 14 |
5 files changed, 67 insertions, 5 deletions
diff --git a/changelogs/fragments/unsafe_for_all.yml b/changelogs/fragments/unsafe_for_all.yml new file mode 100644 index 0000000000..805000ac12 --- /dev/null +++ b/changelogs/fragments/unsafe_for_all.yml @@ -0,0 +1,2 @@ +minor_changes: + - now !unsafe works on all types of data, not just strings, even recursively for mappings and sequences. diff --git a/lib/ansible/parsing/yaml/constructor.py b/lib/ansible/parsing/yaml/constructor.py index 208286e49c..12e271093a 100644 --- a/lib/ansible/parsing/yaml/constructor.py +++ b/lib/ansible/parsing/yaml/constructor.py @@ -24,11 +24,10 @@ from yaml.nodes import MappingNode from ansible import constants as C from ansible.module_utils._text import to_bytes, to_native -from ansible.parsing.yaml.objects import AnsibleMapping, AnsibleSequence, AnsibleUnicode -from ansible.parsing.yaml.objects import AnsibleVaultEncryptedUnicode -from ansible.utils.unsafe_proxy import wrap_var +from ansible.parsing.yaml.objects import AnsibleMapping, AnsibleSequence, AnsibleUnicode, AnsibleVaultEncryptedUnicode from ansible.parsing.vault import VaultLib from ansible.utils.display import Display +from ansible.utils.unsafe_proxy import wrap_var display = Display() @@ -121,7 +120,16 @@ class AnsibleConstructor(SafeConstructor): data.ansible_pos = self._node_position_info(node) def construct_yaml_unsafe(self, node): - return wrap_var(self.construct_yaml_str(node)) + try: + constructor = getattr(node, 'id', 'object') + if constructor is not None: + constructor = getattr(self, 'construct_%s' % constructor) + except AttributeError: + constructor = self.construct_object + + value = constructor(node) + + return wrap_var(value) def _node_position_info(self, node): # the line number where the previous token has ended (plus empty lines) diff --git a/test/integration/targets/yaml_parsing/tasks/main.yml b/test/integration/targets/yaml_parsing/tasks/main.yml index 9446e0d906..7d9c4aa63d 100644 --- a/test/integration/targets/yaml_parsing/tasks/main.yml +++ b/test/integration/targets/yaml_parsing/tasks/main.yml @@ -31,3 +31,7 @@ that: - '"found a duplicate dict key (foo)" not in duplicate_ignore.stderr' - duplicate_ignore.rc == 0 + + +- name: test unsafe YAMLism + import_tasks: unsafe.yml diff --git a/test/integration/targets/yaml_parsing/tasks/unsafe.yml b/test/integration/targets/yaml_parsing/tasks/unsafe.yml new file mode 100644 index 0000000000..8d9d627b72 --- /dev/null +++ b/test/integration/targets/yaml_parsing/tasks/unsafe.yml @@ -0,0 +1,36 @@ +- name: ensure no templating unsafe + block: + - name: check unsafe string + assert: + that: + - regstr != resolved + - "'Fail' not in regstr" + - "'{' in regstr" + - "'}' in regstr" + vars: + regstr: !unsafe b{{nottemplate}} + + - name: check unsafe string in list + assert: + that: + - ulist[0] != resolved + - "'Fail' not in ulist[0]" + - "'{' in ulist[0]" + - "'}' in ulist[0]" + vars: + ulist: !unsafe [ 'b{{nottemplate}}', 'c', 'd'] + + - name: check unsafe string in dict + assert: + that: + - udict['a'] != resolved + - "'Fail' not in udict['a']" + - "'{' in udict['a']" + - "'}' in udict['a']" + vars: + udict: !unsafe + a: b{{nottemplate}} + c: d + vars: + nottemplate: FAIL + resolved: 'b{{nottemplate}}' diff --git a/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py b/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py index ca21cfcbd8..04533d4c69 100644 --- a/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py +++ b/test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py @@ -31,10 +31,22 @@ def main(): class TestConstructor(SafeConstructor): """Yaml Safe Constructor that knows about Ansible tags""" + def construct_yaml_unsafe(self, node): + try: + constructor = getattr(node, 'id', 'object') + if constructor is not None: + constructor = getattr(self, 'construct_%s' % constructor) + except AttributeError: + constructor = self.construct_object + + value = constructor(node) + + return value + TestConstructor.add_constructor( u'!unsafe', - TestConstructor.construct_yaml_str) + TestConstructor.construct_yaml_unsafe) TestConstructor.add_constructor( |