allow any type of unsafe data (#72547)

* allow any type of unsafe data

  dont limit to strings
This commit is contained in:
Brian Coca 2020-11-10 10:48:20 -05:00 committed by GitHub
parent e879f12fb9
commit 48c08f410c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 67 additions and 5 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- now !unsafe works on all types of data, not just strings, even recursively for mappings and sequences.

View file

@ -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)

View file

@ -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

View file

@ -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}}'

View file

@ -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(