Need to convert filenames to byte strings before using them in APIs

Under a non-utf-8 locale (for instance, LC_ALL=C), passing a non-ascii
filename to many APIs will traceback.  Fix that by explicitly converting
to byte strings before passing to external APIs.

May fix #27262
pull/39437/merge
Toshio Kuratomi 6 years ago
parent 3f9e4b16fe
commit 2976b653ce

@ -115,11 +115,12 @@ class ActionModule(ActionBase):
tmp_source = self._loader.get_real_file(source)
except AnsibleFileNotFound as e:
raise AnsibleActionFail("could not find src=%s, %s" % (source, to_text(e)))
b_tmp_source = to_bytes(tmp_source, errors='surrogate_or_strict')
# template the source data locally & get ready to transfer
try:
with open(tmp_source, 'r') as f:
template_data = to_text(f.read())
with open(b_tmp_source, 'rb') as f:
template_data = to_text(f.read(), errors='surrogate_or_strict')
# set jinja2 internal search path for includes
searchpath = task_vars.get('ansible_search_path', [])
@ -159,7 +160,7 @@ class ActionModule(ActionBase):
except Exception as e:
raise AnsibleActionFail("%s: %s" % (type(e).__name__, to_text(e)))
finally:
self._loader.cleanup_tmp_file(tmp_source)
self._loader.cleanup_tmp_file(b_tmp_source)
new_task = self._task.copy()
# mode is either the mode from task.args or the mode of the source file if the task.args
@ -177,7 +178,7 @@ class ActionModule(ActionBase):
try:
result_file = os.path.join(local_tempdir, os.path.basename(source))
with open(result_file, 'wb') as f:
with open(to_bytes(result_file, errors='surrogate_or_strict'), 'wb') as f:
f.write(to_bytes(resultant, errors='surrogate_or_strict'))
new_task.args.update(
@ -196,7 +197,7 @@ class ActionModule(ActionBase):
shared_loader_obj=self._shared_loader_obj)
result.update(copy_action.run(task_vars=task_vars))
finally:
shutil.rmtree(local_tempdir)
shutil.rmtree(to_bytes(local_tempdir, errors='surrogate_or_strict'))
except AnsibleAction as e:
result.update(e.result)

Loading…
Cancel
Save