summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Coca <bcoca@users.noreply.github.com>2020-11-10 10:48:20 -0500
committerGitHub <noreply@github.com>2020-11-10 10:48:20 -0500
commit48c08f410cd368b129fed61f9a58a0cc2b1df458 (patch)
treefa0d449e647f415c0d4a01fd38a33826d8864c5c
parente879f12fb9629842f6c9c1a18ebd9dfd3e23de32 (diff)
downloadansible-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.yml2
-rw-r--r--lib/ansible/parsing/yaml/constructor.py16
-rw-r--r--test/integration/targets/yaml_parsing/tasks/main.yml4
-rw-r--r--test/integration/targets/yaml_parsing/tasks/unsafe.yml36
-rw-r--r--test/lib/ansible_test/_data/sanity/yamllint/yamllinter.py14
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(