Merge pull request #45716 from ciiqr/fix_cmd_script_quoting

fixed quoting of script path in cmd.script
This commit is contained in:
Nicole Thomas 2018-02-02 09:36:48 -05:00 committed by GitHub
commit bd2178cd5f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 1 deletions

View file

@ -36,7 +36,6 @@ from salt.exceptions import CommandExecutionError, TimedProcTimeoutError, \
SaltInvocationError
from salt.log import LOG_LEVELS
from salt.ext.six.moves import range, zip
from salt.ext.six.moves import shlex_quote as _cmd_quote
from salt.utils.locales import sdecode
# Only available on POSIX systems, nonfatal on windows
@ -47,8 +46,10 @@ except ImportError:
if salt.utils.is_windows():
from salt.utils.win_runas import runas as win_runas
from salt.utils.win_functions import escape_argument as _cmd_quote
HAS_WIN_RUNAS = True
else:
from salt.ext.six.moves import shlex_quote as _cmd_quote
HAS_WIN_RUNAS = False
__proxyenabled__ = ['*']

View file

@ -5,6 +5,7 @@ missing functions in other modules
'''
from __future__ import absolute_import
import platform
import re
# Import Salt Libs
from salt.exceptions import CommandExecutionError
@ -159,3 +160,53 @@ def get_sam_name(username):
return '\\'.join([platform.node()[:15].upper(), username])
username, domain, _ = win32security.LookupAccountSid(None, sid_obj)
return '\\'.join([domain, username])
def escape_argument(arg):
'''
Escape the argument for the cmd.exe shell.
See http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
First we escape the quote chars to produce a argument suitable for
CommandLineToArgvW. We don't need to do this for simple arguments.
Args:
arg (str): a single command line argument to escape for the cmd.exe shell
Returns:
str: an escaped string suitable to be passed as a program argument to the cmd.exe shell
'''
if not arg or re.search(r'(["\s])', arg):
arg = '"' + arg.replace('"', r'\"') + '"'
return escape_for_cmd_exe(arg)
def escape_for_cmd_exe(arg):
'''
Escape an argument string to be suitable to be passed to
cmd.exe on Windows
This method takes an argument that is expected to already be properly
escaped for the receiving program to be properly parsed. This argument
will be further escaped to pass the interpolation performed by cmd.exe
unchanged.
Any meta-characters will be escaped, removing the ability to e.g. use
redirects or variables.
Args:
arg (str): a single command line argument to escape for cmd.exe
Returns:
str: an escaped string suitable to be passed as a program argument to cmd.exe
'''
meta_chars = '()%!^"<>&|'
meta_re = re.compile('(' + '|'.join(re.escape(char) for char in list(meta_chars)) + ')')
meta_map = {char: "^{0}".format(char) for char in meta_chars}
def escape_meta_chars(m):
char = m.group(1)
return meta_map[char]
return meta_re.sub(escape_meta_chars, arg)

View file

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# Import Python Libs
from __future__ import absolute_import, unicode_literals, print_function
# Import Salt Testing Libs
from tests.support.unit import TestCase, skipIf
from tests.support.mock import (
NO_MOCK,
NO_MOCK_REASON
)
# Import Salt Libs
import salt.utils.win_functions as win_functions
@skipIf(NO_MOCK, NO_MOCK_REASON)
class WinFunctionsTestCase(TestCase):
'''
Test cases for salt.utils.win_functions
'''
def test_escape_argument_simple(self):
'''
Test to make sure we encode simple arguments correctly
'''
encoded = win_functions.escape_argument('simple')
self.assertEqual(encoded, 'simple')
def test_escape_argument_with_space(self):
'''
Test to make sure we encode arguments containing spaces correctly
'''
encoded = win_functions.escape_argument('with space')
self.assertEqual(encoded, '^"with space^"')
def test_escape_argument_simple_path(self):
'''
Test to make sure we encode simple path arguments correctly
'''
encoded = win_functions.escape_argument('C:\\some\\path')
self.assertEqual(encoded, 'C:\\some\\path')
def test_escape_argument_path_with_space(self):
'''
Test to make sure we encode path arguments containing spaces correctly
'''
encoded = win_functions.escape_argument('C:\\Some Path\\With Spaces')
self.assertEqual(encoded, '^"C:\\Some Path\\With Spaces^"')