Mcsalgado's change to use shlex.quote instead of pipes.quote (#18534)

* Replace pipes.quote for shlex_quote

* More migration of pipes.quote to shlex_quote

Note that we cannot yet move module code over.  Modules have six-1.4
bundled which does not have shlex_quote.  This shouldn't be a problem as
the function is still importable from pipes.quote.  It's just that this
has become an implementation detail that makes us want to import from
shlex instead.

Once we get rid of the python2.4 dependency we can update to a newer
version of bundled six module-side and then we're free to use
shlex_quote everywhere.
pull/18069/merge
Toshio Kuratomi 8 years ago committed by GitHub
parent 5d043b65d3
commit ed00741a01

@ -22,13 +22,13 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import os import os
import pipes
import pwd import pwd
import random import random
import re import re
import string import string
from ansible.compat.six import iteritems, string_types from ansible.compat.six import iteritems, string_types
from ansible.compat.six.moves import shlex_quote
from ansible import constants as C from ansible import constants as C
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
@ -467,7 +467,7 @@ class PlayContext(Base):
becomecmd = None becomecmd = None
randbits = ''.join(random.choice(string.ascii_lowercase) for x in range(32)) randbits = ''.join(random.choice(string.ascii_lowercase) for x in range(32))
success_key = 'BECOME-SUCCESS-%s' % randbits success_key = 'BECOME-SUCCESS-%s' % randbits
success_cmd = pipes.quote('echo %s; %s' % (success_key, cmd)) success_cmd = shlex_quote('echo %s; %s' % (success_key, cmd))
if executable: if executable:
command = '%s -c %s' % (executable, success_cmd) command = '%s -c %s' % (executable, success_cmd)
@ -496,7 +496,7 @@ class PlayContext(Base):
# done for older versions of sudo that do not support the option. # done for older versions of sudo that do not support the option.
# #
# Passing a quoted compound command to sudo (or sudo -s) # Passing a quoted compound command to sudo (or sudo -s)
# directly doesn't work, so we shellquote it with pipes.quote() # directly doesn't work, so we shellquote it with shlex_quote()
# and pass the quoted string to the user's shell. # and pass the quoted string to the user's shell.
# force quick error if password is required but not supplied, should prevent sudo hangs. # force quick error if password is required but not supplied, should prevent sudo hangs.
@ -518,7 +518,7 @@ class PlayContext(Base):
return bool(b_SU_PROMPT_LOCALIZATIONS_RE.match(b_data)) return bool(b_SU_PROMPT_LOCALIZATIONS_RE.match(b_data))
prompt = detect_su_prompt prompt = detect_su_prompt
becomecmd = '%s %s %s -c %s' % (exe, flags, self.become_user, pipes.quote(command)) becomecmd = '%s %s %s -c %s' % (exe, flags, self.become_user, shlex_quote(command))
elif self.become_method == 'pbrun': elif self.become_method == 'pbrun':
@ -562,7 +562,7 @@ class PlayContext(Base):
exe = self.become_exe or 'dzdo' exe = self.become_exe or 'dzdo'
if self.become_pass: if self.become_pass:
prompt = '[dzdo via ansible, key=%s] password: ' % randbits prompt = '[dzdo via ansible, key=%s] password: ' % randbits
becomecmd = '%s -p %s -u %s %s' % (exe, pipes.quote(prompt), self.become_user, command) becomecmd = '%s -p %s -u %s %s' % (exe, shlex_quote(prompt), self.become_user, command)
else: else:
becomecmd = '%s -u %s %s' % (exe, self.become_user, command) becomecmd = '%s -u %s %s' % (exe, self.become_user, command)

@ -22,7 +22,6 @@ __metaclass__ = type
import base64 import base64
import json import json
import os import os
import pipes
import random import random
import re import re
import stat import stat
@ -30,9 +29,9 @@ import tempfile
import time import time
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from ansible.compat.six import binary_type, text_type, iteritems, with_metaclass
from ansible import constants as C from ansible import constants as C
from ansible.compat.six import binary_type, text_type, iteritems, with_metaclass
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError, AnsibleConnectionFailure from ansible.errors import AnsibleError, AnsibleConnectionFailure
from ansible.executor.module_common import modify_module from ansible.executor.module_common import modify_module
from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.module_utils._text import to_bytes, to_native, to_text
@ -596,7 +595,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# the remote system, which can be read and parsed by the module # the remote system, which can be read and parsed by the module
args_data = "" args_data = ""
for k,v in iteritems(module_args): for k,v in iteritems(module_args):
args_data += '%s=%s ' % (k, pipes.quote(text_type(v))) args_data += '%s=%s ' % (k, shlex_quote(text_type(v)))
self._transfer_data(args_file_path, args_data) self._transfer_data(args_file_path, args_data)
elif module_style in ('non_native_want_json', 'binary'): elif module_style in ('non_native_want_json', 'binary'):
self._transfer_data(args_file_path, json.dumps(module_args)) self._transfer_data(args_file_path, json.dumps(module_args))
@ -748,7 +747,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# only applied for the default executable to avoid interfering with the raw action # only applied for the default executable to avoid interfering with the raw action
cmd = self._connection._shell.append_command(cmd, 'sleep 0') cmd = self._connection._shell.append_command(cmd, 'sleep 0')
if executable: if executable:
cmd = executable + ' -c ' + pipes.quote(cmd) cmd = executable + ' -c ' + shlex_quote(cmd)
display.debug("_low_level_execute_command(): executing: %s" % (cmd,)) display.debug("_low_level_execute_command(): executing: %s" % (cmd,))

@ -18,11 +18,11 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import json import json
import pipes
import random import random
from ansible import constants as C from ansible import constants as C
from ansible.compat.six import iteritems from ansible.compat.six import iteritems
from ansible.compat.six.moves import shlex_quote
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
from ansible.plugins.action import ActionBase from ansible.plugins.action import ActionBase
@ -48,8 +48,6 @@ class ActionModule(ActionBase):
module_name = self._task.action module_name = self._task.action
env_string = self._compute_environment_string() env_string = self._compute_environment_string()
module_args = self._task.args.copy() module_args = self._task.args.copy()
@ -77,7 +75,7 @@ class ActionModule(ActionBase):
elif module_style == 'old': elif module_style == 'old':
args_data = "" args_data = ""
for k, v in iteritems(module_args): for k, v in iteritems(module_args):
args_data += '%s="%s" ' % (k, pipes.quote(to_text(v))) args_data += '%s="%s" ' % (k, shlex_quote(to_text(v)))
argsfile = self._transfer_data(self._connection._shell.join_path(tmp, 'arguments'), args_data) argsfile = self._transfer_data(self._connection._shell.join_path(tmp, 'arguments'), args_data)
remote_paths = tmp, remote_module_path, remote_async_module_path remote_paths = tmp, remote_module_path, remote_async_module_path

@ -22,11 +22,11 @@ __metaclass__ = type
import distutils.spawn import distutils.spawn
import os import os
import os.path import os.path
import pipes
import subprocess import subprocess
import traceback import traceback
from ansible import constants as C from ansible import constants as C
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils.basic import is_executable from ansible.module_utils.basic import is_executable
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
@ -128,7 +128,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path) super(Connection, self).put_file(in_path, out_path)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.chroot)
out_path = pipes.quote(self._prefix_login_path(out_path)) out_path = shlex_quote(self._prefix_login_path(out_path))
try: try:
with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file: with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file:
try: try:
@ -150,7 +150,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path) super(Connection, self).fetch_file(in_path, out_path)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.chroot)
in_path = pipes.quote(self._prefix_login_path(in_path)) in_path = shlex_quote(self._prefix_login_path(in_path))
try: try:
p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE))
except OSError: except OSError:

@ -27,13 +27,13 @@ __metaclass__ = type
import distutils.spawn import distutils.spawn
import os import os
import os.path import os.path
import pipes
import subprocess import subprocess
import re import re
from distutils.version import LooseVersion from distutils.version import LooseVersion
import ansible.constants as C import ansible.constants as C
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError, AnsibleFileNotFound from ansible.errors import AnsibleError, AnsibleFileNotFound
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.plugins.connection import ConnectionBase, BUFSIZE
@ -228,7 +228,7 @@ class Connection(ConnectionBase):
raise AnsibleFileNotFound( raise AnsibleFileNotFound(
"file or module does not exist: %s" % in_path) "file or module does not exist: %s" % in_path)
out_path = pipes.quote(out_path) out_path = shlex_quote(out_path)
# Older docker doesn't have native support for copying files into # Older docker doesn't have native support for copying files into
# running containers, so we use docker exec to implement this # running containers, so we use docker exec to implement this
# Although docker version 1.8 and later provide support, the # Although docker version 1.8 and later provide support, the

@ -23,10 +23,10 @@ __metaclass__ = type
import distutils.spawn import distutils.spawn
import os import os
import os.path import os.path
import pipes
import subprocess import subprocess
import traceback import traceback
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.plugins.connection import ConnectionBase, BUFSIZE
@ -150,7 +150,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path) super(Connection, self).put_file(in_path, out_path)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.jail) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.jail)
out_path = pipes.quote(self._prefix_login_path(out_path)) out_path = shlex_quote(self._prefix_login_path(out_path))
try: try:
with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file: with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file:
try: try:
@ -172,7 +172,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path) super(Connection, self).fetch_file(in_path, out_path)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.jail) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.jail)
in_path = pipes.quote(self._prefix_login_path(in_path)) in_path = shlex_quote(self._prefix_login_path(in_path))
try: try:
p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE))
except OSError: except OSError:

@ -23,11 +23,11 @@ __metaclass__ = type
import distutils.spawn import distutils.spawn
import os import os
import os.path import os.path
import pipes
import subprocess import subprocess
import traceback import traceback
from ansible import constants as C from ansible import constants as C
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.plugins.connection import ConnectionBase, BUFSIZE
@ -129,7 +129,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path) super(Connection, self).put_file(in_path, out_path)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.lxc) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.lxc)
out_path = pipes.quote(self._prefix_login_path(out_path)) out_path = shlex_quote(self._prefix_login_path(out_path))
try: try:
with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file: with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file:
try: try:
@ -151,7 +151,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path) super(Connection, self).fetch_file(in_path, out_path)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.lxc) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.lxc)
in_path = pipes.quote(self._prefix_login_path(in_path)) in_path = shlex_quote(self._prefix_login_path(in_path))
try: try:
p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE))
except OSError: except OSError:

@ -22,7 +22,6 @@ __metaclass__ = type
import errno import errno
import fcntl import fcntl
import os import os
import pipes
import pty import pty
import select import select
import subprocess import subprocess
@ -30,6 +29,7 @@ import time
from ansible import constants as C from ansible import constants as C
from ansible.compat.six import PY3, text_type, binary_type from ansible.compat.six import PY3, text_type, binary_type
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
from ansible.errors import AnsibleOptionsError from ansible.errors import AnsibleOptionsError
from ansible.module_utils.basic import BOOLEANS from ansible.module_utils.basic import BOOLEANS
@ -324,7 +324,7 @@ class Connection(ConnectionBase):
Starts the command and communicates with it until it ends. Starts the command and communicates with it until it ends.
''' '''
display_cmd = list(map(pipes.quote, map(to_text, cmd))) display_cmd = list(map(shlex_quote, map(to_text, cmd)))
display.vvv(u'SSH: EXEC {0}'.format(u' '.join(display_cmd)), host=self.host) display.vvv(u'SSH: EXEC {0}'.format(u' '.join(display_cmd)), host=self.host)
# Start the given command. If we don't need to pipeline data, we can try # Start the given command. If we don't need to pipeline data, we can try
@ -626,9 +626,9 @@ class Connection(ConnectionBase):
for method in methods: for method in methods:
if method == 'sftp': if method == 'sftp':
cmd = self._build_command('sftp', to_bytes(host)) cmd = self._build_command('sftp', to_bytes(host))
in_data = u"{0} {1} {2}\n".format(sftp_action, pipes.quote(in_path), pipes.quote(out_path)) in_data = u"{0} {1} {2}\n".format(sftp_action, shlex_quote(in_path), shlex_quote(out_path))
elif method == 'scp': elif method == 'scp':
cmd = self._build_command('scp', in_path, u'{0}:{1}'.format(host, pipes.quote(out_path))) cmd = self._build_command('scp', in_path, u'{0}:{1}'.format(host, shlex_quote(out_path)))
in_data = None in_data = None
in_data = to_bytes(in_data, nonstring='passthru') in_data = to_bytes(in_data, nonstring='passthru')

@ -24,11 +24,11 @@ __metaclass__ = type
import distutils.spawn import distutils.spawn
import os import os
import os.path import os.path
import pipes
import subprocess import subprocess
import traceback import traceback
from ansible import constants as C from ansible import constants as C
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError from ansible.errors import AnsibleError
from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.plugins.connection import ConnectionBase, BUFSIZE
from ansible.module_utils._text import to_bytes from ansible.module_utils._text import to_bytes
@ -149,7 +149,7 @@ class Connection(ConnectionBase):
super(Connection, self).put_file(in_path, out_path) super(Connection, self).put_file(in_path, out_path)
display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.zone) display.vvv("PUT %s TO %s" % (in_path, out_path), host=self.zone)
out_path = pipes.quote(self._prefix_login_path(out_path)) out_path = shlex_quote(self._prefix_login_path(out_path))
try: try:
with open(in_path, 'rb') as in_file: with open(in_path, 'rb') as in_file:
try: try:
@ -171,7 +171,7 @@ class Connection(ConnectionBase):
super(Connection, self).fetch_file(in_path, out_path) super(Connection, self).fetch_file(in_path, out_path)
display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.zone) display.vvv("FETCH %s TO %s" % (in_path, out_path), host=self.zone)
in_path = pipes.quote(self._prefix_login_path(in_path)) in_path = shlex_quote(self._prefix_login_path(in_path))
try: try:
p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE)) p = self._buffered_exec_command('dd if=%s bs=%s' % (in_path, BUFSIZE))
except OSError: except OSError:

@ -25,7 +25,6 @@ import itertools
import json import json
import os.path import os.path
import ntpath import ntpath
import pipes
import glob import glob
import re import re
import crypt import crypt
@ -48,6 +47,7 @@ except:
from ansible import errors from ansible import errors
from ansible.compat.six import iteritems, string_types from ansible.compat.six import iteritems, string_types
from ansible.compat.six.moves import reduce from ansible.compat.six.moves import reduce
from ansible.compat.six.moves import shlex_quote
from ansible.module_utils._text import to_text from ansible.module_utils._text import to_text
from ansible.parsing.yaml.dumper import AnsibleDumper from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.utils.hashing import md5s, checksum_s from ansible.utils.hashing import md5s, checksum_s
@ -123,7 +123,7 @@ def to_datetime(string, format="%Y-%d-%m %H:%M:%S"):
def quote(a): def quote(a):
''' return its argument quoted for shell usage ''' ''' return its argument quoted for shell usage '''
return pipes.quote(a) return shlex_quote(a)
def fileglob(pathname): def fileglob(pathname):
''' return list of matched regular files for glob ''' ''' return list of matched regular files for glob '''

@ -19,15 +19,16 @@ __metaclass__ = type
import os import os
import re import re
import pipes
import ansible.constants as C import ansible.constants as C
import time import time
import random import random
from ansible.compat.six import text_type from ansible.compat.six import text_type
from ansible.compat.six.moves import shlex_quote
_USER_HOME_PATH_RE = re.compile(r'^~[_.A-Za-z0-9][-_.A-Za-z0-9]*$') _USER_HOME_PATH_RE = re.compile(r'^~[_.A-Za-z0-9][-_.A-Za-z0-9]*$')
class ShellBase(object): class ShellBase(object):
def __init__(self): def __init__(self):
@ -44,7 +45,7 @@ class ShellBase(object):
def env_prefix(self, **kwargs): def env_prefix(self, **kwargs):
env = self.env.copy() env = self.env.copy()
env.update(kwargs) env.update(kwargs)
return ' '.join(['%s=%s' % (k, pipes.quote(text_type(v))) for k,v in env.items()]) return ' '.join(['%s=%s' % (k, shlex_quote(text_type(v))) for k,v in env.items()])
def join_path(self, *args): def join_path(self, *args):
return os.path.join(*args) return os.path.join(*args)
@ -60,14 +61,14 @@ class ShellBase(object):
def chmod(self, paths, mode): def chmod(self, paths, mode):
cmd = ['chmod', mode] cmd = ['chmod', mode]
cmd.extend(paths) cmd.extend(paths)
cmd = [pipes.quote(c) for c in cmd] cmd = [shlex_quote(c) for c in cmd]
return ' '.join(cmd) return ' '.join(cmd)
def chown(self, paths, user): def chown(self, paths, user):
cmd = ['chown', user] cmd = ['chown', user]
cmd.extend(paths) cmd.extend(paths)
cmd = [pipes.quote(c) for c in cmd] cmd = [shlex_quote(c) for c in cmd]
return ' '.join(cmd) return ' '.join(cmd)
@ -75,19 +76,19 @@ class ShellBase(object):
"""Only sets acls for users as that's really all we need""" """Only sets acls for users as that's really all we need"""
cmd = ['setfacl', '-m', 'u:%s:%s' % (user, mode)] cmd = ['setfacl', '-m', 'u:%s:%s' % (user, mode)]
cmd.extend(paths) cmd.extend(paths)
cmd = [pipes.quote(c) for c in cmd] cmd = [shlex_quote(c) for c in cmd]
return ' '.join(cmd) return ' '.join(cmd)
def remove(self, path, recurse=False): def remove(self, path, recurse=False):
path = pipes.quote(path) path = shlex_quote(path)
cmd = 'rm -f ' cmd = 'rm -f '
if recurse: if recurse:
cmd += '-r ' cmd += '-r '
return cmd + "%s %s" % (path, self._SHELL_REDIRECT_ALLNULL) return cmd + "%s %s" % (path, self._SHELL_REDIRECT_ALLNULL)
def exists(self, path): def exists(self, path):
cmd = ['test', '-e', pipes.quote(path)] cmd = ['test', '-e', shlex_quote(path)]
return ' '.join(cmd) return ' '.join(cmd)
def mkdtemp(self, basefile=None, system=False, mode=None): def mkdtemp(self, basefile=None, system=False, mode=None):
@ -138,14 +139,14 @@ class ShellBase(object):
# Check that the user_path to expand is safe # Check that the user_path to expand is safe
if user_home_path != '~': if user_home_path != '~':
if not _USER_HOME_PATH_RE.match(user_home_path): if not _USER_HOME_PATH_RE.match(user_home_path):
# pipes.quote will make the shell return the string verbatim # shlex_quote will make the shell return the string verbatim
user_home_path = pipes.quote(user_home_path) user_home_path = shlex_quote(user_home_path)
return 'echo %s' % user_home_path return 'echo %s' % user_home_path
def build_module_command(self, env_string, shebang, cmd, arg_path=None, rm_tmp=None): def build_module_command(self, env_string, shebang, cmd, arg_path=None, rm_tmp=None):
# don't quote the cmd if it's an empty string, because this will break pipelining mode # don't quote the cmd if it's an empty string, because this will break pipelining mode
if cmd.strip() != '': if cmd.strip() != '':
cmd = pipes.quote(cmd) cmd = shlex_quote(cmd)
cmd_parts = [] cmd_parts = []
if shebang: if shebang:

@ -17,9 +17,10 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import pipes
from ansible.plugins.shell.sh import ShellModule as ShModule from ansible.plugins.shell.sh import ShellModule as ShModule
from ansible.compat.six import text_type from ansible.compat.six import text_type
from ansible.compat.six.moves import shlex_quote
class ShellModule(ShModule): class ShellModule(ShModule):
@ -40,12 +41,12 @@ class ShellModule(ShModule):
def env_prefix(self, **kwargs): def env_prefix(self, **kwargs):
env = self.env.copy() env = self.env.copy()
env.update(kwargs) env.update(kwargs)
return ' '.join(['set -lx %s %s;' % (k, pipes.quote(text_type(v))) for k,v in env.items()]) return ' '.join(['set -lx %s %s;' % (k, shlex_quote(text_type(v))) for k,v in env.items()])
def build_module_command(self, env_string, shebang, cmd, arg_path=None, rm_tmp=None): def build_module_command(self, env_string, shebang, cmd, arg_path=None, rm_tmp=None):
# don't quote the cmd if it's an empty string, because this will break pipelining mode # don't quote the cmd if it's an empty string, because this will break pipelining mode
if cmd.strip() != '': if cmd.strip() != '':
cmd = pipes.quote(cmd) cmd = shlex_quote(cmd)
cmd_parts = [env_string.strip(), shebang.replace("#!", "").strip(), cmd] cmd_parts = [env_string.strip(), shebang.replace("#!", "").strip(), cmd]
if arg_path is not None: if arg_path is not None:
cmd_parts.append(arg_path) cmd_parts.append(arg_path)
@ -82,7 +83,7 @@ class ShellModule(ShModule):
# Quoting gets complex here. We're writing a python string that's # Quoting gets complex here. We're writing a python string that's
# used by a variety of shells on the remote host to invoke a python # used by a variety of shells on the remote host to invoke a python
# "one-liner". # "one-liner".
shell_escaped_path = pipes.quote(path) shell_escaped_path = shlex_quote(path)
test = "set rc flag; [ -r %(p)s ] %(shell_or)s set rc 2; [ -f %(p)s ] %(shell_or)s set rc 1; [ -d %(p)s ] %(shell_and)s set rc 3; %(i)s -V 2>/dev/null %(shell_or)s set rc 4; [ x\"$rc\" != \"xflag\" ] %(shell_and)s echo \"$rc \"%(p)s %(shell_and)s exit 0" % dict(p=shell_escaped_path, i=python_interp, shell_and=self._SHELL_AND, shell_or=self._SHELL_OR) test = "set rc flag; [ -r %(p)s ] %(shell_or)s set rc 2; [ -f %(p)s ] %(shell_or)s set rc 1; [ -d %(p)s ] %(shell_and)s set rc 3; %(i)s -V 2>/dev/null %(shell_or)s set rc 4; [ x\"$rc\" != \"xflag\" ] %(shell_and)s echo \"$rc \"%(p)s %(shell_and)s exit 0" % dict(p=shell_escaped_path, i=python_interp, shell_and=self._SHELL_AND, shell_or=self._SHELL_OR)
csums = [ csums = [
u"({0} -c 'import hashlib; BLOCKSIZE = 65536; hasher = hashlib.sha1();{2}afile = open(\"'{1}'\", \"rb\"){2}buf = afile.read(BLOCKSIZE){2}while len(buf) > 0:{2}\thasher.update(buf){2}\tbuf = afile.read(BLOCKSIZE){2}afile.close(){2}print(hasher.hexdigest())' 2>/dev/null)".format(python_interp, shell_escaped_path, self._SHELL_EMBEDDED_PY_EOL), # Python > 2.4 (including python3) u"({0} -c 'import hashlib; BLOCKSIZE = 65536; hasher = hashlib.sha1();{2}afile = open(\"'{1}'\", \"rb\"){2}buf = afile.read(BLOCKSIZE){2}while len(buf) > 0:{2}\thasher.update(buf){2}\tbuf = afile.read(BLOCKSIZE){2}afile.close(){2}print(hasher.hexdigest())' 2>/dev/null)".format(python_interp, shell_escaped_path, self._SHELL_EMBEDDED_PY_EOL), # Python > 2.4 (including python3)

@ -17,8 +17,8 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import pipes
from ansible.compat.six.moves import shlex_quote
from ansible.plugins.shell import ShellBase from ansible.plugins.shell import ShellBase
@ -71,7 +71,7 @@ class ShellModule(ShellBase):
# Quoting gets complex here. We're writing a python string that's # Quoting gets complex here. We're writing a python string that's
# used by a variety of shells on the remote host to invoke a python # used by a variety of shells on the remote host to invoke a python
# "one-liner". # "one-liner".
shell_escaped_path = pipes.quote(path) shell_escaped_path = shlex_quote(path)
test = "rc=flag; [ -r %(p)s ] %(shell_or)s rc=2; [ -f %(p)s ] %(shell_or)s rc=1; [ -d %(p)s ] %(shell_and)s rc=3; %(i)s -V 2>/dev/null %(shell_or)s rc=4; [ x\"$rc\" != \"xflag\" ] %(shell_and)s echo \"${rc} \"%(p)s %(shell_and)s exit 0" % dict(p=shell_escaped_path, i=python_interp, shell_and=self._SHELL_AND, shell_or=self._SHELL_OR) test = "rc=flag; [ -r %(p)s ] %(shell_or)s rc=2; [ -f %(p)s ] %(shell_or)s rc=1; [ -d %(p)s ] %(shell_and)s rc=3; %(i)s -V 2>/dev/null %(shell_or)s rc=4; [ x\"$rc\" != \"xflag\" ] %(shell_and)s echo \"${rc} \"%(p)s %(shell_and)s exit 0" % dict(p=shell_escaped_path, i=python_interp, shell_and=self._SHELL_AND, shell_or=self._SHELL_OR)
csums = [ csums = [
u"({0} -c 'import hashlib; BLOCKSIZE = 65536; hasher = hashlib.sha1();{2}afile = open(\"'{1}'\", \"rb\"){2}buf = afile.read(BLOCKSIZE){2}while len(buf) > 0:{2}\thasher.update(buf){2}\tbuf = afile.read(BLOCKSIZE){2}afile.close(){2}print(hasher.hexdigest())' 2>/dev/null)".format(python_interp, shell_escaped_path, self._SHELL_EMBEDDED_PY_EOL), # Python > 2.4 (including python3) u"({0} -c 'import hashlib; BLOCKSIZE = 65536; hasher = hashlib.sha1();{2}afile = open(\"'{1}'\", \"rb\"){2}buf = afile.read(BLOCKSIZE){2}while len(buf) > 0:{2}\thasher.update(buf){2}\tbuf = afile.read(BLOCKSIZE){2}afile.close(){2}print(hasher.hexdigest())' 2>/dev/null)".format(python_interp, shell_escaped_path, self._SHELL_EMBEDDED_PY_EOL), # Python > 2.4 (including python3)

@ -20,12 +20,12 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import os import os
import pipes
from ansible.compat.tests import unittest from ansible.compat.tests import unittest
from ansible.compat.tests.mock import patch, MagicMock from ansible.compat.tests.mock import patch, MagicMock
from ansible import constants as C from ansible import constants as C
from ansible.compat.six.moves import shlex_quote
from ansible.cli import CLI from ansible.cli import CLI
from ansible.errors import AnsibleError, AnsibleParserError from ansible.errors import AnsibleError, AnsibleParserError
from ansible.playbook.play_context import PlayContext from ansible.playbook.play_context import PlayContext
@ -181,7 +181,7 @@ class TestPlayContext(unittest.TestCase):
play_context.become_pass = 'testpass' play_context.become_pass = 'testpass'
play_context.become_method = 'dzdo' play_context.become_method = 'dzdo'
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
self.assertEqual(cmd, """%s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, pipes.quote(play_context.prompt), play_context.become_user, default_exe, play_context.success_key, default_cmd)) self.assertEqual(cmd, """%s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, shlex_quote(play_context.prompt), play_context.become_user, default_exe, play_context.success_key, default_cmd))
class TestTaskAndVariableOverrride(unittest.TestCase): class TestTaskAndVariableOverrride(unittest.TestCase):

@ -20,7 +20,6 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import pipes
import os import os
try: try:
@ -32,6 +31,7 @@ from nose.tools import eq_, raises
from ansible import constants as C from ansible import constants as C
from ansible.compat.six import text_type from ansible.compat.six import text_type
from ansible.compat.six.moves import shlex_quote
from ansible.compat.tests import unittest from ansible.compat.tests import unittest
from ansible.compat.tests.mock import patch, MagicMock, mock_open from ansible.compat.tests.mock import patch, MagicMock, mock_open
@ -164,7 +164,7 @@ class TestActionBase(unittest.TestCase):
# create a mock connection, so we don't actually try and connect to things # create a mock connection, so we don't actually try and connect to things
def env_prefix(**args): def env_prefix(**args):
return ' '.join(['%s=%s' % (k, pipes.quote(text_type(v))) for k,v in args.items()]) return ' '.join(['%s=%s' % (k, shlex_quote(text_type(v))) for k,v in args.items()])
mock_connection = MagicMock() mock_connection = MagicMock()
mock_connection._shell.env_prefix.side_effect = env_prefix mock_connection._shell.env_prefix.side_effect = env_prefix

@ -21,13 +21,13 @@
from __future__ import (absolute_import, division, print_function) from __future__ import (absolute_import, division, print_function)
__metaclass__ = type __metaclass__ = type
import pipes
from io import StringIO from io import StringIO
from ansible.compat.tests import unittest from ansible.compat.tests import unittest
from ansible.compat.tests.mock import patch, MagicMock from ansible.compat.tests.mock import patch, MagicMock
from ansible import constants as C from ansible import constants as C
from ansible.compat.six.moves import shlex_quote
from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound
from ansible.playbook.play_context import PlayContext from ansible.playbook.play_context import PlayContext
from ansible.plugins.connection import ssh from ansible.plugins.connection import ssh
@ -311,7 +311,7 @@ class TestConnectionBaseClass(unittest.TestCase):
# Test with C.DEFAULT_SCP_IF_SSH set to smart # Test with C.DEFAULT_SCP_IF_SSH set to smart
# Test when SFTP works # Test when SFTP works
C.DEFAULT_SCP_IF_SSH = 'smart' C.DEFAULT_SCP_IF_SSH = 'smart'
expected_in_data = b' '.join((b'put', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' expected_in_data = b' '.join((b'put', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n'
conn.put_file('/path/to/in/file', '/path/to/dest/file') conn.put_file('/path/to/in/file', '/path/to/dest/file')
conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False)
@ -331,13 +331,13 @@ class TestConnectionBaseClass(unittest.TestCase):
# test with C.DEFAULT_SCP_IF_SSH disabled # test with C.DEFAULT_SCP_IF_SSH disabled
C.DEFAULT_SCP_IF_SSH = False C.DEFAULT_SCP_IF_SSH = False
expected_in_data = b' '.join((b'put', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' expected_in_data = b' '.join((b'put', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n'
conn.put_file('/path/to/in/file', '/path/to/dest/file') conn.put_file('/path/to/in/file', '/path/to/dest/file')
conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False)
expected_in_data = b' '.join((b'put', expected_in_data = b' '.join((b'put',
to_bytes(pipes.quote('/path/to/in/file/with/unicode-fö〩')), to_bytes(shlex_quote('/path/to/in/file/with/unicode-fö〩')),
to_bytes(pipes.quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n' to_bytes(shlex_quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n'
conn.put_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩') conn.put_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩')
conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False)
@ -365,7 +365,7 @@ class TestConnectionBaseClass(unittest.TestCase):
# Test with C.DEFAULT_SCP_IF_SSH set to smart # Test with C.DEFAULT_SCP_IF_SSH set to smart
# Test when SFTP works # Test when SFTP works
C.DEFAULT_SCP_IF_SSH = 'smart' C.DEFAULT_SCP_IF_SSH = 'smart'
expected_in_data = b' '.join((b'get', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' expected_in_data = b' '.join((b'get', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n'
conn.fetch_file('/path/to/in/file', '/path/to/dest/file') conn.fetch_file('/path/to/in/file', '/path/to/dest/file')
conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False)
@ -385,13 +385,13 @@ class TestConnectionBaseClass(unittest.TestCase):
# test with C.DEFAULT_SCP_IF_SSH disabled # test with C.DEFAULT_SCP_IF_SSH disabled
C.DEFAULT_SCP_IF_SSH = False C.DEFAULT_SCP_IF_SSH = False
expected_in_data = b' '.join((b'get', to_bytes(pipes.quote('/path/to/in/file')), to_bytes(pipes.quote('/path/to/dest/file')))) + b'\n' expected_in_data = b' '.join((b'get', to_bytes(shlex_quote('/path/to/in/file')), to_bytes(shlex_quote('/path/to/dest/file')))) + b'\n'
conn.fetch_file('/path/to/in/file', '/path/to/dest/file') conn.fetch_file('/path/to/in/file', '/path/to/dest/file')
conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False)
expected_in_data = b' '.join((b'get', expected_in_data = b' '.join((b'get',
to_bytes(pipes.quote('/path/to/in/file/with/unicode-fö〩')), to_bytes(shlex_quote('/path/to/in/file/with/unicode-fö〩')),
to_bytes(pipes.quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n' to_bytes(shlex_quote('/path/to/dest/file/with/unicode-fö〩')))) + b'\n'
conn.fetch_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩') conn.fetch_file(u'/path/to/in/file/with/unicode-fö〩', u'/path/to/dest/file/with/unicode-fö〩')
conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False) conn._run.assert_called_with('some command to run', expected_in_data, checkrc=False)

Loading…
Cancel
Save