Skip to content

Commit

Permalink
Modified powershell encoding to use " instead of '
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolas-van committed Apr 25, 2023
1 parent e592952 commit 186cf7a
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 21 deletions.
3 changes: 1 addition & 2 deletions test_ressources/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
import shutil
import subprocess
import locale

echo_py_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "echo.py"))

Expand All @@ -30,7 +29,7 @@ def run_echoer_with_cmd_through_script(str):
finally:
shutil.rmtree(tmp_folder)

def run_echoer_with_cmd_through_python_subprocess(str):
def run_echoer_with_cmd_direct(str):
tmp_folder = tempfile.mkdtemp()
try:
# create the bat file
Expand Down
46 changes: 39 additions & 7 deletions test_win_cmd_escaper.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import win_cmd_escaper
import test_ressources.test_utils as test_utils

powershell_supported_control_characters = ['\n', '\t', '\b', '\v']

class AllTests:

def _test_str(self, string):
Expand Down Expand Up @@ -62,18 +64,21 @@ def test_printable_ascii_doubled_in_text(self):
character = chr(i)
self._test_str(f"a{character}{character}b")

def test_control_characters(self):
def test_unsupported_control_characters(self):
for i in range(0, 32):
character = chr(i)
if character in set(powershell_supported_control_characters):
continue
self._test_unsupported(character)
self._test_unsupported("\r")
self._test_unsupported("\n")
self._test_unsupported("\t")

def test_no_variable_substitution_batch(self):
self._test_str("%a%")
self._test_str("%%a%%")

def test_no_variable_substitution_powershell(self):
self._test_str("$a")
self._test_str("hello $a world")

def test_backslash(self):
self._test_str("\\")
self._test_str("\\\\")
Expand Down Expand Up @@ -105,21 +110,44 @@ def test_double_quotes(self):
self._test_str('"\\\\')
self._test_str('"\\\\\\')

class CmdScriptTests(unittest.TestCase, AllTests):
def test_backticks(self):
self._test_str('`')
self._test_str('``')
self._test_str('```')
self._test_str('\\`')
self._test_str('\\\\`')
self._test_str('\\\\\\`')
self._test_str('hello\\`')
self._test_str('hello\\\\`')
self._test_str('hello\\\\\\`')
self._test_str('\\`hello')
self._test_str('\\\\`hello')
self._test_str('\\\\\\`hello')
self._test_str('`\\')
self._test_str('`\\\\')
self._test_str('`\\\\\\')

class AllCmdTests(AllTests):

def test_other_control_characters(self):
for c in powershell_supported_control_characters:
self._test_unsupported(c)

class CmdScriptTests(unittest.TestCase, AllCmdTests):

def escape(self, str):
return win_cmd_escaper.escape_cmd_argument_script(str)

def run_echoer(self, str):
return test_utils.run_echoer_with_cmd_through_script(str)

class CmdDirectTests(unittest.TestCase, AllTests):
class CmdDirectTests(unittest.TestCase, AllCmdTests):

def escape(self, str):
return win_cmd_escaper.escape_cmd_argument_direct(str)

def run_echoer(self, str):
return test_utils.run_echoer_with_cmd_through_python_subprocess(str)
return test_utils.run_echoer_with_cmd_direct(str)


class PowershellScriptTests(unittest.TestCase, AllTests):
Expand All @@ -130,6 +158,10 @@ def escape(self, str):
def run_echoer(self, str):
return test_utils.run_echoer_with_powershell_through_script(str)

def test_other_control_characters(self):
for c in powershell_supported_control_characters:
self._test_str(c)

def test_latin_1(self):
self._test_str('Aéèàù')

Expand Down
28 changes: 16 additions & 12 deletions win_cmd_escaper.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,22 @@ def escape_powershell_argument_script(str):
acc = ""
for i in range(len(str)):
c = str[i]
if ord(c) < 32:
if c == '\n':
acc += '`n'
elif c == '\t':
acc += '`t'
elif c == '\b':
acc += '`b'
elif c == '\v':
acc += '`v'
elif ord(c) < 32:
raise ValueError("ASCII control codes are not supported")
elif c == "'":
acc += "''"
elif c == '"':
bs_count = 0
for j in range(i - 1, -1, -1):
if str[j] == '\\':
bs_count += 1
else:
break
acc += ('\\' * bs_count) + '\\"'
elif c == "\"":
acc += "`\""
elif c == '`':
acc += "``"
elif c == '$':
acc += "`$"
else:
acc += c
return f"'{acc}'"
return f'"{acc}"'

0 comments on commit 186cf7a

Please sign in to comment.