diff options
author | Toshio Kuratomi <a.badger@gmail.com> | 2017-02-24 10:01:21 -0800 |
---|---|---|
committer | Toshio Kuratomi <a.badger@gmail.com> | 2017-02-24 12:19:28 -0800 |
commit | d45f2d3288b89145679d63b1fa6534547d6aa151 (patch) | |
tree | 4692852887c6799d8bb92e92a0663d766bb92dcf | |
parent | e9e39e4fd6ebd04bcd0a00603946e185758a2060 (diff) | |
download | ansible-d45f2d3288b89145679d63b1fa6534547d6aa151.tar.gz |
Fix for traceback when we encounter non-utf8 characters in diff
We can diff non-utf8 files (as part of copy, for instance) but when we
try to turn the bytes into text for display, the characters cause
a traceback. Since diff output is only informational, we can replace
those problematic bytes with replacement characters. We do not want to
do this to other fields because those fields may be used inside of the
playbook (for templating another variable or matching in a conditional).
Fixes #21803
Fixes #21804
(cherry picked from commit 49db03c384b63ba7a299263cdae63857fe46ef1f)
-rw-r--r-- | lib/ansible/executor/task_executor.py | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/lib/ansible/executor/task_executor.py b/lib/ansible/executor/task_executor.py index 59759245a8..21a29052d1 100644 --- a/lib/ansible/executor/task_executor.py +++ b/lib/ansible/executor/task_executor.py @@ -130,17 +130,26 @@ class TaskExecutor: if 'changed' not in res: res['changed'] = False - def _clean_res(res): + def _clean_res(res, errors='surrogate_or_strict'): if isinstance(res, UnsafeProxy): return res._obj elif isinstance(res, binary_type): - return to_text(res, errors='surrogate_or_strict') + return to_text(res, errors=errors) elif isinstance(res, dict): for k in res: - res[k] = _clean_res(res[k]) + try: + res[k] = _clean_res(res[k], errors=errors) + except UnicodeError: + if k == 'diff': + # If this is a diff, substitute a replacement character if the value + # is undecodable as utf8. (Fix #21804) + display.warning("We were unable to decode all characters, replaced some in an effort to return as much as possible") + res[k] = _clean_res(res[k], errors='surrogate_then_replace') + else: + raise elif isinstance(res, list): for idx,item in enumerate(res): - res[idx] = _clean_res(item) + res[idx] = _clean_res(item, errors=errors) return res display.debug("dumping result to json") |