Skip to content

Commit bb39384

Browse files
authored
{Util} Add a centralized function for subprocess (#29745)
* add centenralized func * add tests
1 parent ff015a2 commit bb39384

File tree

4 files changed

+36
-179
lines changed

4 files changed

+36
-179
lines changed

src/azure-cli-core/azure/cli/core/cli_subprocess.py

Lines changed: 0 additions & 108 deletions
This file was deleted.

src/azure-cli-core/azure/cli/core/tests/test_cli_subprocess.py

Lines changed: 0 additions & 70 deletions
This file was deleted.

src/azure-cli-core/azure/cli/core/tests/test_util.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
from unittest import mock
1212
import tempfile
1313
import json
14+
import platform
1415

1516
from azure.cli.core.util import \
1617
(get_file_json, truncate_text, shell_safe_json_parse, b64_to_hex, hash_string, random_string,
1718
open_page_in_browser, can_launch_browser, handle_exception, ConfiguredDefaultSetter, send_raw_request,
1819
should_disable_connection_verify, parse_proxy_resource_id, get_az_user_agent, get_az_rest_user_agent,
19-
_get_parent_proc_name, is_wsl)
20+
_get_parent_proc_name, is_wsl, run_cmd)
2021
from azure.cli.core.mock import DummyCli
2122

2223

@@ -421,6 +422,26 @@ def test_get_parent_proc_name(self, mock_process_type):
421422
parent2.name.return_value = "bash"
422423
self.assertEqual(_get_parent_proc_name(), "pwsh")
423424

425+
def test_cli_run_cmd(self):
426+
cmd = ["echo", "abc"]
427+
if platform.system().lower() == "windows":
428+
cmd = ["cmd.exe", "/c"] + cmd
429+
output = run_cmd(cmd, capture_output=True)
430+
self.assertEqual(output.returncode, 0, "error when run cmd in shell")
431+
self.assertEqual(output.stdout.decode("utf8").strip(), "abc", "unexpected output when run cmd")
432+
433+
output = run_cmd(cmd, capture_output=True, encoding="utf8")
434+
self.assertEqual(output.returncode, 0, "error when run cmd in shell")
435+
self.assertEqual(output.stdout.strip(), "abc", "unexpected output when run cmd")
436+
437+
def test_run_cmd_arg_error(self):
438+
cmd = "echo abc"
439+
if platform.system().lower() == "windows":
440+
cmd = "cmd.exe /c " + cmd
441+
from azure.cli.core.azclierror import ArgumentUsageError
442+
with self.assertRaises(ArgumentUsageError):
443+
run_cmd(cmd, check=True)
444+
424445

425446
class TestBase64ToHex(unittest.TestCase):
426447

src/azure-cli-core/azure/cli/core/util.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1356,3 +1356,17 @@ def should_encrypt_token_cache(cli_ctx):
13561356
encrypt = cli_ctx.config.getboolean('core', 'encrypt_token_cache', fallback=fallback)
13571357

13581358
return encrypt
1359+
1360+
1361+
def run_cmd(args, *, capture_output=False, timeout=None, check=False, encoding=None, env=None):
1362+
"""Run command in a subprocess. It reduces (not eliminates) shell injection by forcing args to be a list
1363+
and shell=False. Other arguments are keyword-only. For their documentation, see
1364+
https://docs.python.org/3/library/subprocess.html#subprocess.run
1365+
"""
1366+
if not isinstance(args, list):
1367+
from azure.cli.core.azclierror import ArgumentUsageError
1368+
raise ArgumentUsageError("Invalid args. run_cmd args must be a list")
1369+
1370+
import subprocess
1371+
return subprocess.run(args, capture_output=capture_output, timeout=timeout, check=check,
1372+
encoding=encoding, env=env)

0 commit comments

Comments
 (0)