mirror of
https://github.com/nimbold/Firelink.git
synced 2026-09-01 13:38:01 +00:00
fix(media): harden bundled engine ownership
- Fail closed on CWD engine fallback in release builds. - Redact media process diagnostics and remove unused Aria2 resolution. - Add release-mode resolver regression coverage and rerun media gates.
This commit is contained in:
@@ -11,7 +11,7 @@ pub fn resolve_bundled_binary_path(
|
||||
if let Ok(resource_dir) = app_handle.path().resource_dir() {
|
||||
for candidate in packaged_candidates(&resource_dir, &target, &binary_name) {
|
||||
if candidate.is_file() {
|
||||
log::info!("Resolved bundled '{}' at: {:?}", engine, candidate);
|
||||
log::info!("Resolved bundled '{}' for target '{}'", engine, target);
|
||||
return Ok(candidate);
|
||||
}
|
||||
}
|
||||
@@ -20,19 +20,24 @@ pub fn resolve_bundled_binary_path(
|
||||
if let Ok(exe_path) = std::env::current_exe() {
|
||||
for candidate in executable_relative_candidates(&exe_path, &target, &binary_name) {
|
||||
if candidate.is_file() {
|
||||
log::info!("Resolved bundled '{}' at: {:?}", engine, candidate);
|
||||
log::info!("Resolved bundled '{}' for target '{}'", engine, target);
|
||||
return Ok(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Development payloads are intentionally discoverable from the checkout,
|
||||
// but a packaged/release app must never execute an engine selected by its
|
||||
// working directory. If the packaged resource or executable-relative
|
||||
// payload is missing, fail closed instead of allowing a same-named binary
|
||||
// from an untrusted CWD to take over the media/download process.
|
||||
if let Ok(cwd) = std::env::current_dir() {
|
||||
for candidate in development_candidates(&cwd, &target, &binary_name) {
|
||||
for candidate in development_candidates_for_runtime(&cwd, &target, &binary_name) {
|
||||
if candidate.is_file() {
|
||||
let absolute = candidate.canonicalize().map_err(|error| {
|
||||
format!("Failed to canonicalize '{}': {error}", candidate.display())
|
||||
})?;
|
||||
log::info!("Resolved bundled '{}' at: {:?}", engine, absolute);
|
||||
log::info!("Resolved bundled '{}' for target '{}'", engine, target);
|
||||
return Ok(absolute);
|
||||
}
|
||||
}
|
||||
@@ -44,6 +49,22 @@ pub fn resolve_bundled_binary_path(
|
||||
))
|
||||
}
|
||||
|
||||
fn development_candidates_for_runtime(
|
||||
cwd: &Path,
|
||||
target: &str,
|
||||
binary_name: &str,
|
||||
) -> Vec<PathBuf> {
|
||||
#[cfg(debug_assertions)]
|
||||
{
|
||||
development_candidates(cwd, target, binary_name)
|
||||
}
|
||||
#[cfg(not(debug_assertions))]
|
||||
{
|
||||
let _ = (cwd, target, binary_name);
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
|
||||
fn packaged_candidates(resource_dir: &Path, target: &str, binary_name: &str) -> Vec<PathBuf> {
|
||||
let mut candidates = vec![
|
||||
resource_dir
|
||||
@@ -98,6 +119,7 @@ fn executable_relative_candidates(
|
||||
candidates
|
||||
}
|
||||
|
||||
#[cfg(any(debug_assertions, test))]
|
||||
fn development_candidates(cwd: &Path, target: &str, binary_name: &str) -> Vec<PathBuf> {
|
||||
let roots = [cwd.to_path_buf(), cwd.join("src-tauri")];
|
||||
let mut candidates = Vec::new();
|
||||
@@ -141,7 +163,7 @@ fn aria2_openssl_modules_dir(binary_path: &Path) -> Option<PathBuf> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{development_candidates, packaged_candidates};
|
||||
use super::{development_candidates, development_candidates_for_runtime, packaged_candidates};
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
@@ -171,4 +193,19 @@ mod tests {
|
||||
Path::new("/repo/engine-dist/x86_64-pc-windows-msvc/aria2c-x86_64-pc-windows-msvc.exe")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn development_resolution_is_disabled_in_release_builds() {
|
||||
let candidates = development_candidates_for_runtime(
|
||||
Path::new("/repo"),
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"yt-dlp-x86_64-unknown-linux-gnu",
|
||||
);
|
||||
|
||||
if cfg!(debug_assertions) {
|
||||
assert!(!candidates.is_empty());
|
||||
} else {
|
||||
assert!(candidates.is_empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+12
-9
@@ -4754,12 +4754,10 @@ pub(crate) async fn start_media_download_internal(
|
||||
let mut progress_state = MediaProgressEmitterState::new();
|
||||
|
||||
// Resolve absolute paths to bundled binaries
|
||||
let aria2c_path = resolve_bundled_binary_path(&app_handle, "aria2c")?;
|
||||
let ffmpeg_path = resolve_bundled_binary_path(&app_handle, "ffmpeg")?;
|
||||
let deno_path = resolve_bundled_binary_path(&app_handle, "deno")?;
|
||||
log::info!("Using bundled aria2c: {:?}", aria2c_path);
|
||||
log::info!("Using bundled ffmpeg: {:?}", ffmpeg_path);
|
||||
log::info!("Using bundled deno: {:?}", deno_path);
|
||||
log::info!("Using bundled FFmpeg engine");
|
||||
log::info!("Using bundled Deno engine");
|
||||
|
||||
// yt-dlp accepts an absolute path for its external downloader. Keep every
|
||||
// engine explicit so behavior never depends on PATH, symlink privileges,
|
||||
@@ -4982,13 +4980,18 @@ pub(crate) async fn start_media_download_internal(
|
||||
}
|
||||
let lower = line.to_lowercase();
|
||||
if lower.contains("error") || lower.contains("critical") {
|
||||
log::error!("yt-dlp stderr [{}]: {}", id, line.trim());
|
||||
log::error!(
|
||||
"yt-dlp stderr [{}]: {}",
|
||||
id,
|
||||
redact_log_line_for_app(line.trim(), &app_handle)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(tauri_plugin_shell::process::CommandEvent::Error(err)) => {
|
||||
log::error!("yt-dlp shell error [{}]: {}", id, err);
|
||||
break err;
|
||||
let safe_error = redact_log_line_for_app(&err, &app_handle);
|
||||
log::error!("yt-dlp shell error [{}]: {}", id, safe_error);
|
||||
break safe_error;
|
||||
}
|
||||
Some(tauri_plugin_shell::process::CommandEvent::Terminated(payload)) => {
|
||||
if let Some(line) = flush_media_output_line(&mut stdout_buffer) {
|
||||
@@ -5065,7 +5068,7 @@ pub(crate) async fn start_media_download_internal(
|
||||
break if stderr_tail.is_empty() {
|
||||
format!("yt-dlp exited with code {:?}", payload.code)
|
||||
} else {
|
||||
stderr_tail.clone()
|
||||
redact_log_line_for_app(&stderr_tail, &app_handle)
|
||||
};
|
||||
}
|
||||
Some(_) => {}
|
||||
@@ -5073,7 +5076,7 @@ pub(crate) async fn start_media_download_internal(
|
||||
break if stderr_tail.is_empty() {
|
||||
"yt-dlp process ended unexpectedly".to_string()
|
||||
} else {
|
||||
stderr_tail.clone()
|
||||
redact_log_line_for_app(&stderr_tail, &app_handle)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user