Avoid subshells when using check_output
authorJohn Carr <john.carr@unrouted.co.uk>
Tue, 25 Jun 2024 12:56:04 +0000 (13:56 +0100)
committerJohn Carr <john.carr@unrouted.co.uk>
Tue, 25 Jun 2024 12:56:04 +0000 (13:56 +0100)
music_assistant/server/helpers/audio.py
music_assistant/server/providers/airplay/__init__.py
music_assistant/server/providers/filesystem_smb/__init__.py
music_assistant/server/providers/snapcast/__init__.py

index 3aa30d3274d22553727e4c9008e4dc465541e021..721c544702ef0013b701ac9ac9eca7f8393d80e2 100644 (file)
@@ -819,7 +819,7 @@ async def get_ffmpeg_stream(
 async def check_audio_support() -> tuple[bool, bool, str]:
     """Check if ffmpeg is present (with/without libsoxr support)."""
     # check for FFmpeg presence
-    returncode, output = await check_output("ffmpeg -version")
+    returncode, output = await check_output(["ffmpeg", "-version"])
     ffmpeg_present = returncode == 0 and "FFmpeg" in output.decode()
 
     # use globals as in-memory cache
index 7f6d0027812c982310e042c885663ad1316b27e6..aadab9aa11f6e4ab24341cf1df0feea345783dc7 100644 (file)
@@ -723,7 +723,7 @@ class AirplayProvider(PlayerProvider):
                 empty_queue(buffer)
 
         # get current ntp and start cliraop
-        _, stdout = await check_output(f"{self.cliraop_bin} -ntp")
+        _, stdout = await check_output(self.cliraop_bin, "-ntp")
         start_ntp = int(stdout.strip())
         wait_start = 1250 + (250 * len(sync_clients))
         await asyncio.gather(
index 6a068dd863a59d43cd72ed9e2c85fd4b35d97628..1ad7d3efc70cf22c59a1745da42013fc1e106091 100644 (file)
@@ -186,7 +186,13 @@ class SMBFileSystemProvider(LocalFileSystemProvider):
 
         if platform.system() == "Darwin":
             password_str = f":{password}" if password else ""
-            mount_cmd = f'mount -t smbfs "//{username}:{password_str}@{server}/{share}{subfolder}" "{self.base_path}"'  # noqa: E501
+            mount_cmd = [
+                "mount",
+                "-t",
+                "smbfs",
+                f"//{username}:{password_str}@{server}/{share}{subfolder}",
+                self.base_path,
+            ]
 
         elif platform.system() == "Linux":
             options = [
@@ -199,10 +205,15 @@ class SMBFileSystemProvider(LocalFileSystemProvider):
                 options += mount_options.split(",")
 
             options_str = ",".join(options)
-            mount_cmd = (
-                f"mount -t cifs -o {options_str} "
-                f'"//{server}/{share}{subfolder}" "{self.base_path}"'
-            )
+            mount_cmd = [
+                "mount",
+                "-t",
+                "cifs",
+                "-o",
+                options_str,
+                f"//{server}/{share}{subfolder}",
+                self.base_path,
+            ]
 
         else:
             msg = f"SMB provider is not supported on {platform.system()}"
@@ -218,6 +229,6 @@ class SMBFileSystemProvider(LocalFileSystemProvider):
 
     async def unmount(self, ignore_error: bool = False) -> None:
         """Unmount the remote share."""
-        returncode, output = await check_output(f"umount {self.base_path}")
+        returncode, output = await check_output(["umount", self.base_path])
         if returncode != 0 and not ignore_error:
             self.logger.warning("SMB unmount failed with error: %s", output.decode())
index b448150f319962e785f40740a1857b6a17297fc3..b562e0143ba8d78884a3c9d96d6f3e10cf38f573 100644 (file)
@@ -108,7 +108,7 @@ async def get_config_entries(
     action: [optional] action key called from config entries UI.
     values: the (intermediate) raw values for config entries sent with the action.
     """
-    returncode, output = await check_output("snapserver -v")
+    returncode, output = await check_output(["snapserver", "-v"])
     snapserver_present = returncode == 0 and "snapserver v0.27.0" in output.decode()
     return (
         ConfigEntry(