From 49fe53266fca026f87ed4c49009bd7aa0454591e Mon Sep 17 00:00:00 2001 From: Evan Kaufman Date: Mon, 5 Jun 2017 19:35:18 -0700 Subject: [PATCH] Replace - workaround for non-utf8 text (#24861) * Workaround for non-utf8 text exceptions * Added encoding param, using to convert from bytes to text and back Fixes ansible/ansible#24521 --- lib/ansible/modules/files/replace.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/ansible/modules/files/replace.py b/lib/ansible/modules/files/replace.py index ff82ce5f0ab..141b753b84a 100644 --- a/lib/ansible/modules/files/replace.py +++ b/lib/ansible/modules/files/replace.py @@ -168,7 +168,7 @@ def write_changes(module, contents, path): tmpfd, tmpfile = tempfile.mkstemp() f = os.fdopen(tmpfd,'wb') - f.write(to_bytes(contents)) + f.write(contents) f.close() validate = module.params.get('validate', None) @@ -208,6 +208,7 @@ def main(): before=dict(required=False), backup=dict(default=False, type='bool'), validate=dict(default=None, type='str'), + encoding=dict(default='utf-8', type='str'), ), add_file_common_args=True, supports_check_mode=True @@ -215,8 +216,14 @@ def main(): params = module.params path = params['path'] + encoding = params['encoding'] res_args = dict() + params['after'] = to_text(params['after'], errors='surrogate_or_strict', nonstring='passthru') + params['before'] = to_text(params['before'], errors='surrogate_or_strict', nonstring='passthru') + params['regexp'] = to_text(params['regexp'], errors='surrogate_or_strict', nonstring='passthru') + params['replace'] = to_text(params['replace'], errors='surrogate_or_strict', nonstring='passthru') + if os.path.isdir(path): module.fail_json(rc=256, msg='Path %s is a directory !' % path) @@ -224,16 +231,16 @@ def main(): module.fail_json(rc=257, msg='Path %s does not exist !' % path) else: f = open(path, 'rb') - contents = to_text(f.read(), errors='surrogate_or_strict') + contents = to_text(f.read(), errors='surrogate_or_strict', encoding=encoding) f.close() - pattern = '' - if params['after']: - pattern = '%s(.*)' % params['after'] + pattern = u'' + if params['after'] and params['before']: + pattern = u'%s(.*?)%s' % (params['before'], params['after']) + elif params['after']: + pattern = u'%s(.*)' % params['after'] elif params['before']: - pattern = '(.*)%s' % params['before'] - elif params['after'] and params['before']: - pattern = '%s(.*?)%s' % (params['before'], params['after']) + pattern = u'(.*)%s' % params['before'] if pattern: section_re = re.compile(pattern, re.DOTALL) @@ -269,7 +276,7 @@ def main(): res_args['backup_file'] = module.backup_local(path) if params['follow'] and os.path.islink(path): path = os.path.realpath(path) - write_changes(module, result[0], path) + write_changes(module, to_bytes(result[0], encoding=encoding), path) res_args['msg'], res_args['changed'] = check_file_attrs(module, changed, msg) module.exit_json(**res_args)