From 287d2f94da2f376d4b22084527d0c460c2033e6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Fri, 11 Sep 2026 18:59:51 +0800 Subject: [PATCH] =?UTF-8?q?=E9=99=90=E5=88=B6=E8=87=AA=E5=8A=A8=E5=88=87?= =?UTF-8?q?=E5=88=86=E6=81=A2=E5=A4=8D=E7=8A=B6=E6=80=81=E8=AF=BB=E5=8F=96?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在解析 sidecar state 前检查文件大小,避免异常分配。 --- .../commands/separation/persistence.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/persistence.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/persistence.rs index 80fd9f0a2..32b49adc6 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/persistence.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/persistence.rs @@ -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 { 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 { .and_then(|name| name.to_str()) .unwrap_or("") ); + 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}")