限制自动切分恢复状态读取大小

在解析 sidecar state 前检查文件大小,避免异常分配。
This commit is contained in:
2026-09-11 18:59:51 +08:00
parent 1343f487d0
commit 287d2f94da
@@ -2,6 +2,8 @@ use super::model::*;
use crate::ui_editor::commands::separation::*;
use std::fs;
use std::path::{Path, PathBuf};
const SEPARATION_STATE_MAX_BYTES: usize = 8 * 1024 * 1024;
pub fn separation_sidecar_dir(root: &Path, asset_id: &str) -> Result<PathBuf, String> {
if asset_id.trim().is_empty() || asset_id.trim() != asset_id {
app_log!("ui_separation.error stage=sidecar_dir reason=invalid_asset_id");
@@ -97,10 +99,31 @@ pub fn read_separation_state(path: &Path) -> Result<SeparationState, String> {
.and_then(|name| name.to_str())
.unwrap_or("<unknown>")
);
let metadata = fs::metadata(path).map_err(|error| {
app_log!("ui_separation.error stage=state_read reason=metadata error={error}");
format!("读取 separation state 信息失败:{error}")
})?;
if metadata.len() > SEPARATION_STATE_MAX_BYTES as u64 {
app_log!(
"ui_separation.error stage=state_read reason=too_large bytes={} max_bytes={}",
metadata.len(),
SEPARATION_STATE_MAX_BYTES
);
return Err(format!(
"separation state 超过 {} 字节上限",
SEPARATION_STATE_MAX_BYTES
));
}
let bytes = fs::read(path).map_err(|error| {
app_log!("ui_separation.error stage=state_read reason=read error={error}");
format!("读取 separation state 失败:{error}")
})?;
if bytes.len() > SEPARATION_STATE_MAX_BYTES {
return Err(format!(
"separation state 超过 {} 字节上限",
SEPARATION_STATE_MAX_BYTES
));
}
let state: SeparationState = serde_json::from_slice(&bytes).map_err(|error| {
app_log!("ui_separation.error stage=state_read reason=parse error={error}");
format!("解析 separation state 失败:{error}")