refactor: 移除输入路径的 validate_safe_path 验证,放宽文件访问限制
This commit is contained in:
@@ -60,50 +60,10 @@ fn normalize_path(path: &std::path::Path) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// 验证路径在允许的目录内,防止路径遍历攻击
|
||||
/// 允许的目录:应用数据目录(app_local_data_dir)
|
||||
fn validate_safe_path(path: &str) -> Result<String, String> {
|
||||
let path = std::path::Path::new(path);
|
||||
|
||||
// 获取绝对路径
|
||||
let abs_path = if path.is_absolute() {
|
||||
path.to_path_buf()
|
||||
} else {
|
||||
std::env::current_dir()
|
||||
.map_err(|e| format!("无法获取当前目录: {}", e))?
|
||||
.join(path)
|
||||
};
|
||||
|
||||
// 检查是否在允许的目录内
|
||||
let allowed_dir = crate::storage::paths::get_app_data_dir()
|
||||
.map_err(|e| format!("无法获取应用数据目录: {}", e))?;
|
||||
|
||||
// 规范化路径
|
||||
let canonical = abs_path.canonicalize()
|
||||
.unwrap_or(abs_path.clone());
|
||||
|
||||
// 同时规范化允许目录(Windows 上 canonicalize 会添加 \\?\ 前缀,
|
||||
// 必须与输入路径保持一致的规范化格式才能正确比较)
|
||||
let allowed_canonical = allowed_dir.canonicalize()
|
||||
.unwrap_or(allowed_dir.clone());
|
||||
|
||||
// 检查是否在允许目录下
|
||||
if !canonical.starts_with(&allowed_canonical) {
|
||||
return Err(format!("路径不在允许目录内: {}", path.display()));
|
||||
}
|
||||
|
||||
Ok(canonical.to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
/// 清理并验证输出路径
|
||||
/// 清理输出路径(转绝对路径)
|
||||
pub fn sanitize_output_path(path: &str) -> Result<String, String> {
|
||||
let path = std::path::Path::new(path);
|
||||
|
||||
// 获取父目录并验证
|
||||
if let Some(parent) = path.parent() {
|
||||
validate_safe_path(&parent.to_string_lossy())?;
|
||||
}
|
||||
|
||||
// 确保是绝对路径
|
||||
if path.is_absolute() {
|
||||
Ok(path.to_string_lossy().to_string())
|
||||
@@ -215,8 +175,7 @@ pub async fn standardize_video(
|
||||
target_width: u32,
|
||||
target_height: u32,
|
||||
) -> Result<(), String> {
|
||||
// 验证路径安全
|
||||
let safe_input = validate_safe_path(input_path)?;
|
||||
let safe_input = input_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let vf = format!(
|
||||
@@ -244,8 +203,7 @@ pub async fn standardize_video(
|
||||
* 拼接视频 - 快速模式 (要求编码/分辨率一致)
|
||||
*/
|
||||
pub async fn concat_videos_copy(app: &AppHandle, list_path: &str, output_path: &str) -> Result<(), String> {
|
||||
// 验证路径安全
|
||||
let safe_list = validate_safe_path(list_path)?;
|
||||
let safe_list = list_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let args = vec![
|
||||
@@ -321,9 +279,8 @@ pub async fn concat_videos_robust(
|
||||
* 音画合并 - 优化音质
|
||||
*/
|
||||
pub async fn add_audio_to_video(app: &AppHandle, video_path: &str, audio_path: &str, output_path: &str) -> Result<(), String> {
|
||||
// 验证路径安全
|
||||
let safe_video = validate_safe_path(video_path)?;
|
||||
let safe_audio = validate_safe_path(audio_path)?;
|
||||
let safe_video = video_path.to_string();
|
||||
let safe_audio = audio_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let args = vec![
|
||||
@@ -353,8 +310,7 @@ pub async fn create_cover_video(
|
||||
target_width: u32,
|
||||
target_height: u32,
|
||||
) -> Result<(), String> {
|
||||
// 验证路径安全
|
||||
let safe_input = validate_safe_path(input_path)?;
|
||||
let safe_input = input_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let vf = format!(
|
||||
@@ -491,13 +447,13 @@ pub async fn burn_ass_subtitle(
|
||||
output_path: &str,
|
||||
overlay_image: Option<&str>,
|
||||
) -> Result<(), String> {
|
||||
// 输入路径验证:HTTP URL 直接传递,本地文件需要安全检查
|
||||
// 输入路径:HTTP URL 直接传递,本地文件直接传递
|
||||
let safe_video = if video_path.starts_with("http://") || video_path.starts_with("https://") {
|
||||
video_path.to_string()
|
||||
} else {
|
||||
validate_safe_path(video_path)?
|
||||
video_path.to_string()
|
||||
};
|
||||
let safe_ass = validate_safe_path(ass_path)?;
|
||||
let safe_ass = ass_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
// 准备临时工作目录(ASS + 字体),使用相对路径避开 Windows C: 盘符问题
|
||||
@@ -505,7 +461,7 @@ pub async fn burn_ass_subtitle(
|
||||
|
||||
// 如果有 overlay 图片,先 overlay 再 burn 字幕(两步避免 filter_complex 音频映射问题)
|
||||
if let Some(img_path) = overlay_image {
|
||||
let safe_img = validate_safe_path(img_path)?;
|
||||
let safe_img = img_path.to_string();
|
||||
let temp_output = format!("{}.tmp_overlay.mp4", safe_output);
|
||||
|
||||
// Step 1: overlay PNG 到视频
|
||||
@@ -588,14 +544,8 @@ pub async fn mix_bgm_to_video(
|
||||
video_volume: f64,
|
||||
bgm_volume: f64,
|
||||
) -> Result<(), String> {
|
||||
let safe_video = validate_safe_path(video_path)?;
|
||||
// BGM 可以是用户通过系统文件选择器选取的任意本地文件,
|
||||
// 验证文件存在且不含路径遍历字符
|
||||
let safe_bgm = if !bgm_path.contains("..") && std::path::Path::new(bgm_path).exists() {
|
||||
bgm_path.to_string()
|
||||
} else {
|
||||
return Err(format!("BGM 文件不存在或路径非法: {}", bgm_path));
|
||||
};
|
||||
let safe_video = video_path.to_string();
|
||||
let safe_bgm = bgm_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
// 构建 filter_complex:
|
||||
@@ -635,9 +585,8 @@ pub async fn replace_audio_track(
|
||||
audio_path: &str,
|
||||
output_path: &str,
|
||||
) -> Result<(), String> {
|
||||
// 验证路径安全
|
||||
let safe_video = validate_safe_path(video_path)?;
|
||||
let safe_audio = validate_safe_path(audio_path)?;
|
||||
let safe_video = video_path.to_string();
|
||||
let safe_audio = audio_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let args = vec![
|
||||
@@ -839,7 +788,7 @@ pub async fn extract_audio_segment(
|
||||
duration: f64,
|
||||
output_path: &str,
|
||||
) -> Result<(), String> {
|
||||
let safe_input = validate_safe_path(input_path)?;
|
||||
let safe_input = input_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let start_str = format!("{:.3}", start);
|
||||
@@ -873,7 +822,7 @@ pub async fn extract_audio_from_video(
|
||||
input_path: &str,
|
||||
output_path: &str,
|
||||
) -> Result<(), String> {
|
||||
let safe_input = validate_safe_path(input_path)?;
|
||||
let safe_input = input_path.to_string();
|
||||
let safe_output = sanitize_output_path(output_path)?;
|
||||
|
||||
let args = vec![
|
||||
|
||||
Reference in New Issue
Block a user