From 6f2366dc2d3d33c90c250f59d1a20d7d41ed8631 Mon Sep 17 00:00:00 2001 From: diiviikk5 Date: Sun, 8 Feb 2026 01:44:02 +0530 Subject: [PATCH] fix: replace os.system() with subprocess.run() for security and robustness - Replace os.system() calls with subprocess.run() using list args to avoid shell injection (CWE-78, Bandit B605/B607) - Replace assert-based error handling with proper exceptions (ValueError, RuntimeError, FileNotFoundError) that survive python -O (Bandit B101) - Use sys.executable instead of hardcoded 'python' to ensure correct interpreter (Bandit B607) Files changed: cmake_build.py, scripts/run_tests.py, compileall.py, amalgamate.py --- amalgamate.py | 8 +++++--- cmake_build.py | 23 +++++++++++++++-------- compileall.py | 8 +++++--- scripts/run_tests.py | 17 +++++++++-------- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/amalgamate.py b/amalgamate.py index 0026f5dd..c44e63e9 100644 --- a/amalgamate.py +++ b/amalgamate.py @@ -3,9 +3,10 @@ import shutil import os import sys import time +import subprocess from typing import List, Dict -assert os.system("python prebuild.py") == 0 +subprocess.run([sys.executable, "prebuild.py"], check=True) ROOT = 'include/pocketpy' PUBLIC_HEADERS = ['config.h', 'export.h', 'vmath.h', 'pocketpy.h'] @@ -161,8 +162,9 @@ write_file('amalgamated/pocketpy.h', merge_h_files()) shutil.copy("src2/main.c", "amalgamated/main.c") def checked_sh(cmd): - ok = os.system(cmd) - assert ok == 0, f"command failed: {cmd}" + result = subprocess.run(cmd, shell=True) + if result.returncode != 0: + raise RuntimeError(f"command failed (exit code {result.returncode}): {cmd}") if sys.platform in ['linux', 'darwin']: common_flags = "-O1 --std=c11 -lm -ldl -lpthread -Iamalgamated" diff --git a/cmake_build.py b/cmake_build.py index 954f9650..1eb95b27 100644 --- a/cmake_build.py +++ b/cmake_build.py @@ -1,8 +1,9 @@ -import os +import subprocess import sys import shutil +import os -assert os.system("python prebuild.py") == 0 +subprocess.run([sys.executable, "prebuild.py"], check=True) if not os.path.exists("build"): os.mkdir("build") @@ -14,16 +15,22 @@ if len(sys.argv) > 1: else: config = 'Release' -extra_flags = " ".join(sys.argv[2:]) +extra_flags = sys.argv[2:] -assert config in ['Debug', 'Release', 'RelWithDebInfo'] +if config not in ['Debug', 'Release', 'RelWithDebInfo']: + raise ValueError(f"Invalid config: {config!r}. Must be one of Debug, Release, RelWithDebInfo") os.chdir("build") -code = os.system(f"cmake .. -DPK_ENABLE_MIMALLOC=ON -DPK_ENABLE_DETERMINISM=ON -DCMAKE_BUILD_TYPE={config} {extra_flags}") -assert code == 0 -code = os.system(f"cmake --build . --config {config} -j 4") -assert code == 0 +subprocess.run( + ["cmake", "..", "-DPK_ENABLE_MIMALLOC=ON", "-DPK_ENABLE_DETERMINISM=ON", + f"-DCMAKE_BUILD_TYPE={config}"] + extra_flags, + check=True, +) +subprocess.run( + ["cmake", "--build", ".", "--config", config, "-j", "4"], + check=True, +) if sys.platform == "win32": shutil.copy(f"{config}/main.exe", "../main.exe") diff --git a/compileall.py b/compileall.py index d010aa7b..9c5f10ee 100644 --- a/compileall.py +++ b/compileall.py @@ -1,5 +1,6 @@ import sys import os +import subprocess if len(sys.argv) != 4: print('Usage: python compileall.py ') @@ -10,9 +11,10 @@ source_dir = sys.argv[2] output_dir = sys.argv[3] def do_compile(src_path, dst_path): - assert os.path.isfile(src_path) - cmd = f'{pkpy_exe} --compile "{src_path}" "{dst_path}"' - if os.system(cmd) != 0: + if not os.path.isfile(src_path): + raise FileNotFoundError(f"Source file not found: {src_path}") + result = subprocess.run([pkpy_exe, '--compile', src_path, dst_path]) + if result.returncode != 0: print(src_path) exit(1) diff --git a/scripts/run_tests.py b/scripts/run_tests.py index 3b37be18..6b2b91f3 100644 --- a/scripts/run_tests.py +++ b/scripts/run_tests.py @@ -7,11 +7,12 @@ pkpy_exe = 'main.exe' if sys.platform == 'win32' else './main' def test_file(filepath, cpython=False): if cpython: - return os.system("python " + filepath) == 0 - code = os.system(pkpy_exe + ' ' + filepath) - if code != 0: - print('Return code:', code) - return code == 0 + result = subprocess.run([sys.executable, filepath]) + return result.returncode == 0 + result = subprocess.run([pkpy_exe, filepath]) + if result.returncode != 0: + print('Return code:', result.returncode) + return result.returncode == 0 def test_dir(path): print("Testing directory:", path) @@ -74,11 +75,11 @@ exit() print(res.stdout) exit(1) -code = os.system(f'python compileall.py {pkpy_exe} tests tmp/tests') -assert code == 0 +subprocess.run([sys.executable, 'compileall.py', pkpy_exe, 'tests', 'tmp/tests'], check=True) if len(sys.argv) == 2: - assert 'benchmark' in sys.argv[1] + if 'benchmark' not in sys.argv[1]: + raise ValueError(f"Expected 'benchmark' in argument, got: {sys.argv[1]!r}") test_dir('benchmarks/') else: test_dir('tests/')