Harden yt-dlp binary resolution and analysis subprocess handling
- get_yt_dlp_path() no longer implicitly executes a bare "yt-dlp" from PATH (on Windows that lookup includes the CWD, so a planted binary in a writable directory could be run). A system yt-dlp is used only behind the explicit advanced.allow_system_ytdlp config opt-in, and then always as a which()-resolved absolute path. Analysis and download refuse to exec the not-installed sentinel. - Analysis subprocesses now run in their own session and the whole process group is killed on timeout, so deno grandchildren no longer leak; partial stderr is preserved and logged, and output decoding is pinned to utf-8 with replacement (Windows locale codecs crashed on non-UTF8 titles). - Flat-playlist entries are filtered for None (private/deleted first video no longer breaks analysis). - update_yt_dlp() normalizes the sentinel to Path, unbreaking the pip fallback path that crashed on str.exists(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -244,8 +244,12 @@ class DownloadThread(QThread):
|
||||
def _build_yt_dlp_command(self) -> List[str]:
|
||||
"""Build the yt-dlp command line with all options for direct execution."""
|
||||
yt_dlp_path: str = get_yt_dlp_path()
|
||||
if str(yt_dlp_path) == "yt-dlp":
|
||||
# Sentinel: no managed binary and no opted-in system binary.
|
||||
# Never exec a bare command name from PATH.
|
||||
raise FileNotFoundError("yt-dlp is not installed - run the yt-dlp setup first")
|
||||
# Build the command line array
|
||||
cmd: List[str] = [yt_dlp_path]
|
||||
cmd: List[str] = [str(yt_dlp_path)]
|
||||
logger.debug(f"Using yt-dlp from: {yt_dlp_path}")
|
||||
|
||||
# Add concurrent fragments setting
|
||||
|
||||
Reference in New Issue
Block a user