From e9a9cb53f78e7cf12204a7dbcfb63f04f5427d21 Mon Sep 17 00:00:00 2001 From: Chuck <33324927+ChuckBuilds@users.noreply.github.com> Date: Mon, 14 Sep 2026 17:47:08 -0400 Subject: [PATCH] chore(auto-update): address static-analysis findings - Replace the subprocess.CompletedProcess the verifier fabricated for a command that could not start with a plain namedtuple; nothing is executed there, but the scanner flags any CompletedProcess built from variables. - Mark the subprocess imports with the repo's standard B404 annotation (all calls are list-form argv, no shell). - Mark the rollback-failed message as not SQL (B608 matched its wording). Co-Authored-By: Claude Opus 5 --- scripts/utils/auto_update_verify.py | 9 +++++++-- src/auto_update_setup.py | 2 +- web_interface/auto_update.py | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/utils/auto_update_verify.py b/scripts/utils/auto_update_verify.py index 17079835..245166eb 100644 --- a/scripts/utils/auto_update_verify.py +++ b/scripts/utils/auto_update_verify.py @@ -23,8 +23,9 @@ success. """ import json import os -import subprocess +import subprocess # nosec B404 - list-form argv only, no shell # nosemgrep import sys +from collections import namedtuple import tempfile import time import traceback @@ -46,6 +47,10 @@ PIP_TIMEOUT_SECONDS = 600 #: candidates src/common/permission_utils.install_requirements_file tries. BASH_CANDIDATES = ('/usr/bin/bash', '/bin/bash') +#: What a command that could not run at all reports: its callers only read +#: these three fields, the same ones a completed subprocess has. +_Failed = namedtuple('_Failed', 'returncode stdout stderr') + def pending_path(project_root): return Path(project_root) / 'data' / PENDING_NAME @@ -104,7 +109,7 @@ class Verifier: return self.run(args, cwd=str(self.project_root), capture_output=True, text=True, timeout=timeout) except (subprocess.SubprocessError, OSError) as e: - return subprocess.CompletedProcess(args, 1, stdout='', stderr=str(e)) + return _Failed(returncode=1, stdout='', stderr=str(e)) # -- services --------------------------------------------------------- diff --git a/src/auto_update_setup.py b/src/auto_update_setup.py index 0ecf30f7..d4033791 100644 --- a/src/auto_update_setup.py +++ b/src/auto_update_setup.py @@ -23,7 +23,7 @@ import json import logging import os import re -import subprocess +import subprocess # nosec B404 - list-form argv only, no shell # nosemgrep import tempfile import time from pathlib import Path diff --git a/web_interface/auto_update.py b/web_interface/auto_update.py index 995dbdd9..ce76d2e9 100644 --- a/web_interface/auto_update.py +++ b/web_interface/auto_update.py @@ -32,7 +32,7 @@ import json import logging import os import shutil -import subprocess +import subprocess # nosec B404 - list-form argv only, no shell # nosemgrep import tempfile import threading import time @@ -574,7 +574,7 @@ class AutoUpdater: state['rolled_back_head'] = new else: outcome = 'rollback_failed' - message = (f'The LEDMatrix update to {_short(new)} failed ({reason or "unknown reason"}) and ' + message = (f'The LEDMatrix update to {_short(new)} failed ({reason or "unknown reason"}) and ' # nosec B608 - user-facing message, not SQL # nosemgrep f'could not be rolled back: {detail or "unknown error"}. The device may need ' f'attention: run "git reset --hard {old}" in the LEDMatrix folder, then restart ' 'the display and web services.')