fix(rust): Windows 路径验证失败(canonicalize UNC 前缀不匹配)
在 Windows 上 std::fs::canonicalize() 会返回 \?\ 前缀的 UNC 路径 (如 \?\C:\Users\...),但 get_app_data_dir() 返回普通路径格式 (C:\Users\...)。PathBuf::starts_with() 做组件级比较时两者前缀 类型不同导致返回 false,所有本地文件操作都被错误拒绝。 修复:对允许目录也做 canonicalize(),使两边格式一致后再比较。 影响文件: - ffmpeg_cmd.rs: validate_safe_path() - commands/product.rs: delete_local_product, rename_local_product, export_product
This commit is contained in:
@@ -219,8 +219,9 @@ pub async fn delete_local_product(path: String) -> ApiResponse<()> {
|
||||
data: None,
|
||||
},
|
||||
};
|
||||
let app_data_canonical = app_data.canonicalize().unwrap_or_else(|_| app_data.clone());
|
||||
|
||||
if !canonical.starts_with(app_data) {
|
||||
if !canonical.starts_with(&app_data_canonical) {
|
||||
return ApiResponse {
|
||||
code: 400,
|
||||
message: "路径不在允许范围内".to_string(),
|
||||
@@ -279,8 +280,9 @@ pub async fn rename_local_product(path: String, new_filename: String) -> ApiResp
|
||||
data: None,
|
||||
},
|
||||
};
|
||||
let app_data_canonical = app_data.canonicalize().unwrap_or_else(|_| app_data.clone());
|
||||
|
||||
if !canonical.starts_with(app_data) {
|
||||
if !canonical.starts_with(&app_data_canonical) {
|
||||
return ApiResponse {
|
||||
code: 400,
|
||||
message: "路径不在允许范围内".to_string(),
|
||||
@@ -359,8 +361,9 @@ pub async fn export_product(source_path: String, target_path: String) -> ApiResp
|
||||
data: None,
|
||||
},
|
||||
};
|
||||
let app_data_canonical = app_data.canonicalize().unwrap_or_else(|_| app_data.clone());
|
||||
|
||||
if !source_canonical.starts_with(app_data) {
|
||||
if !source_canonical.starts_with(&app_data_canonical) {
|
||||
return ApiResponse {
|
||||
code: 400,
|
||||
message: "源文件不在允许范围内".to_string(),
|
||||
|
||||
@@ -51,8 +51,13 @@ fn validate_safe_path(path: &str) -> Result<String, String> {
|
||||
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_dir) {
|
||||
if !canonical.starts_with(&allowed_canonical) {
|
||||
return Err(format!("路径不在允许目录内: {}", path.display()));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user