diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/workflow/extract.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/workflow/extract.rs index f55db59e3..9477e2a37 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/workflow/extract.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/workflow/extract.rs @@ -5,6 +5,27 @@ use std::path::PathBuf; use std::time::Instant; use std::{fs, io::Cursor}; +const MAX_IMAGE_PAYLOAD_BYTES: usize = 64 * 1024 * 1024; + +fn decode_bounded_base64(value: &str, label: &str) -> Result, String> { + if value.len() > (MAX_IMAGE_PAYLOAD_BYTES / 3) * 4 + 4 { + return Err(format!( + "{label}超过 {} MiB 字节上限", + MAX_IMAGE_PAYLOAD_BYTES / 1024 / 1024 + )); + } + let decoded = base64::engine::general_purpose::STANDARD + .decode(value.trim()) + .map_err(|error| format!("解码{label}失败:{error}"))?; + if decoded.len() > MAX_IMAGE_PAYLOAD_BYTES { + return Err(format!( + "{label}超过 {} MiB 字节上限", + MAX_IMAGE_PAYLOAD_BYTES / 1024 / 1024 + )); + } + Ok(decoded) +} + #[derive(Deserialize)] struct RawEditResponse { data: Vec, @@ -54,9 +75,7 @@ async fn raw_extract_inner( .strip_prefix("data:") .and_then(|value| value.strip_suffix(";base64")); let is_png = mime.is_some_and(|value| value.eq_ignore_ascii_case("image/png")); - let image_bytes = base64::engine::general_purpose::STANDARD - .decode(data.trim()) - .map_err(|error| format!("解码源图失败:{error}"))?; + let image_bytes = decode_bounded_base64(data, "源图")?; if image_bytes.is_empty() { return Err("源图不能为空".to_string()); } @@ -199,9 +218,7 @@ async fn write_processed_image_inner( .split_once(',') .map(|(_, data)| data) .ok_or_else(|| "处理图 data URL 无效".to_string())?; - let processed_bytes = base64::engine::general_purpose::STANDARD - .decode(encoded) - .map_err(|error| format!("解析处理图失败:{error}"))?; + let processed_bytes = decode_bounded_base64(encoded, "处理图")?; let dimensions = image::ImageReader::new(Cursor::new(processed_bytes.as_slice())) .with_guessed_format() .map_err(|error| format!("识别处理图格式失败:{error}"))?