mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Fixes for module param counting and additional shell quoting issues
This commit is contained in:
parent
091b76efaa
commit
2cc602beea
2 changed files with 24 additions and 16 deletions
|
@ -389,7 +389,7 @@ class Runner(object):
|
||||||
|
|
||||||
return actual_user
|
return actual_user
|
||||||
|
|
||||||
def _count_module_args(self, args):
|
def _count_module_args(self, args, allow_dupes=False):
|
||||||
'''
|
'''
|
||||||
Count the number of k=v pairs in the supplied module args. This is
|
Count the number of k=v pairs in the supplied module args. This is
|
||||||
basically a specialized version of parse_kv() from utils with a few
|
basically a specialized version of parse_kv() from utils with a few
|
||||||
|
@ -399,22 +399,25 @@ class Runner(object):
|
||||||
if args is not None:
|
if args is not None:
|
||||||
args = args.encode('utf-8')
|
args = args.encode('utf-8')
|
||||||
try:
|
try:
|
||||||
lexer = shlex.shlex(args, posix=True)
|
lexer = shlex.shlex(args)
|
||||||
|
lexer.whitespace = '\t '
|
||||||
lexer.whitespace_split = True
|
lexer.whitespace_split = True
|
||||||
lexer.quotes = '"'
|
vargs = [x.decode('utf-8') for x in lexer]
|
||||||
lexer.ignore_quotes = "'"
|
|
||||||
vargs = list(lexer)
|
|
||||||
except ValueError, ve:
|
except ValueError, ve:
|
||||||
if 'no closing quotation' in str(ve).lower():
|
if 'no closing quotation' in str(ve).lower():
|
||||||
raise errors.AnsibleError("error parsing argument string '%s', try quoting the entire line." % args)
|
raise errors.AnsibleError("error parsing argument string '%s', try quoting the entire line." % args)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
vargs = [x.decode('utf-8') for x in vargs]
|
|
||||||
for x in vargs:
|
for x in vargs:
|
||||||
if "=" in x:
|
quoted = x.startswith('"') and x.endswith('"') or x.startswith("'") and x.endswith("'")
|
||||||
|
if "=" in x and not quoted:
|
||||||
k, v = x.split("=",1)
|
k, v = x.split("=",1)
|
||||||
if k in options:
|
is_shell_module = self.module_name in ('command', 'shell')
|
||||||
|
is_shell_param = k in ('creates', 'removes', 'chdir', 'executable')
|
||||||
|
if k in options and not allow_dupes:
|
||||||
|
if not(is_shell_module and not is_shell_param):
|
||||||
raise errors.AnsibleError("a duplicate parameter was found in the argument string (%s)" % k)
|
raise errors.AnsibleError("a duplicate parameter was found in the argument string (%s)" % k)
|
||||||
|
if is_shell_module and is_shell_param or not is_shell_module:
|
||||||
options[k] = v
|
options[k] = v
|
||||||
return len(options)
|
return len(options)
|
||||||
|
|
||||||
|
@ -863,7 +866,7 @@ class Runner(object):
|
||||||
# that no variables inadvertantly (or maliciously) add params
|
# that no variables inadvertantly (or maliciously) add params
|
||||||
# to the list of args. We do this by counting the number of k=v
|
# to the list of args. We do this by counting the number of k=v
|
||||||
# pairs before and after templating.
|
# pairs before and after templating.
|
||||||
num_args_pre = self._count_module_args(module_args)
|
num_args_pre = self._count_module_args(module_args, allow_dupes=True)
|
||||||
module_args = template.template(self.basedir, module_args, inject, fail_on_undefined=self.error_on_undefined_vars)
|
module_args = template.template(self.basedir, module_args, inject, fail_on_undefined=self.error_on_undefined_vars)
|
||||||
num_args_post = self._count_module_args(module_args)
|
num_args_post = self._count_module_args(module_args)
|
||||||
if num_args_pre != num_args_post:
|
if num_args_pre != num_args_post:
|
||||||
|
|
|
@ -213,16 +213,21 @@ class CommandModule(AnsibleModule):
|
||||||
|
|
||||||
# use shlex to split up the args, while being careful to preserve
|
# use shlex to split up the args, while being careful to preserve
|
||||||
# single quotes so they're not removed accidentally
|
# single quotes so they're not removed accidentally
|
||||||
lexer = shlex.shlex(args, posix=True)
|
lexer = shlex.shlex(args)
|
||||||
|
lexer.whitespace = '\t '
|
||||||
lexer.whitespace_split = True
|
lexer.whitespace_split = True
|
||||||
lexer.quotes = '"'
|
|
||||||
lexer.ignore_quotes = "'"
|
|
||||||
items = list(lexer)
|
items = list(lexer)
|
||||||
|
|
||||||
for x in items:
|
for x in items:
|
||||||
if '=' in x:
|
quoted = x.startswith('"') and x.endswith('"') or x.startswith("'") and x.endswith("'")
|
||||||
|
if '=' in x and not quoted:
|
||||||
# check to see if this is a special parameter for the command
|
# check to see if this is a special parameter for the command
|
||||||
k, v = x.split('=', 1)
|
k, v = x.split('=', 1)
|
||||||
|
# because we're not breaking out quotes in the shlex split
|
||||||
|
# above, the value of the k=v pair may still be quoted. If
|
||||||
|
# so, remove them.
|
||||||
|
if len(v) > 1 and (v.startswith('"') and v.endswith('"') or v.startswith("'") and v.endswith("'")):
|
||||||
|
v = v[1:-1]
|
||||||
if k in ('creates', 'removes', 'chdir', 'executable', 'NO_LOG'):
|
if k in ('creates', 'removes', 'chdir', 'executable', 'NO_LOG'):
|
||||||
if k == "chdir":
|
if k == "chdir":
|
||||||
v = os.path.abspath(os.path.expanduser(v))
|
v = os.path.abspath(os.path.expanduser(v))
|
||||||
|
@ -235,7 +240,7 @@ class CommandModule(AnsibleModule):
|
||||||
params[k] = v
|
params[k] = v
|
||||||
# Remove any of the above k=v params from the args string
|
# Remove any of the above k=v params from the args string
|
||||||
args = PARAM_REGEX.sub('', args)
|
args = PARAM_REGEX.sub('', args)
|
||||||
params['args'] = args
|
params['args'] = args.strip()
|
||||||
return (params, params['args'])
|
return (params, params['args'])
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Reference in a new issue