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
This commit is contained in:
Toshio Kuratomi 2017-02-24 10:01:21 -08:00
parent b714f1fc4b
commit 49db03c384

View file

@ -129,17 +129,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")