diff --git a/changelogs/fragments/unsafe-fixes-2.yml b/changelogs/fragments/unsafe-fixes-2.yml new file mode 100644 index 00000000000..ffb4cae740c --- /dev/null +++ b/changelogs/fragments/unsafe-fixes-2.yml @@ -0,0 +1,3 @@ +bugfixes: +- unsafe data - Address an incompatibility with ``AnsibleUnsafeText`` and ``AnsibleUnsafeBytes`` when pickling with ``protocol=0`` +- unsafe data - Address an incompatibility when iterating or getting a single index from ``AnsibleUnsafeBytes`` diff --git a/lib/ansible/utils/unsafe_proxy.py b/lib/ansible/utils/unsafe_proxy.py index 7f9593f478e..683f6e27df6 100644 --- a/lib/ansible/utils/unsafe_proxy.py +++ b/lib/ansible/utils/unsafe_proxy.py @@ -71,6 +71,9 @@ class AnsibleUnsafeBytes(bytes, AnsibleUnsafe): def _strip_unsafe(self): return super().__bytes__() + def __reduce__(self, /): + return (self.__class__, (self._strip_unsafe(),)) + def __str__(self, /): # pylint: disable=invalid-str-returned return self.decode() @@ -84,12 +87,10 @@ class AnsibleUnsafeBytes(bytes, AnsibleUnsafe): return AnsibleUnsafeText(super().__format__(format_spec)) def __getitem__(self, key, /): + if isinstance(key, int): + return super().__getitem__(key) return self.__class__(super().__getitem__(key)) - def __iter__(self, /): - cls = self.__class__ - return (cls(c) for c in super().__iter__()) - def __reversed__(self, /): return self[::-1] @@ -192,6 +193,9 @@ class AnsibleUnsafeText(str, AnsibleUnsafe): def _strip_unsafe(self, /): return super().__str__() + def __reduce__(self, /): + return (self.__class__, (self._strip_unsafe(),)) + def __str__(self, /): # pylint: disable=invalid-str-returned return self diff --git a/test/integration/targets/filter_urls/tasks/main.yml b/test/integration/targets/filter_urls/tasks/main.yml index c062326c54e..72ed689a700 100644 --- a/test/integration/targets/filter_urls/tasks/main.yml +++ b/test/integration/targets/filter_urls/tasks/main.yml @@ -19,6 +19,13 @@ - "{'foo': 'bar', 'baz': 'buz'}|urlencode == 'foo=bar&baz=buz'" - "()|urlencode == ''" +- name: verify urlencode works for unsafe strings + assert: + that: + - thing|urlencode == 'foo%3Abar' + vars: + thing: !unsafe foo:bar + # Needed (temporarily) due to coverage reports not including the last task. - assert: that: true