diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/image_preprocess.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/image_preprocess.rs index d04782faf..147a6dce1 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/image_preprocess.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/separation/image_preprocess.rs @@ -1,11 +1,13 @@ use super::area::MIN_VISIBLE_ALPHA; use base64::Engine as _; -use image::{ImageFormat, Rgba, RgbaImage}; +use image::{ImageFormat, ImageReader, Rgba, RgbaImage}; use std::fs; use std::io::Cursor; use std::path::{Path, PathBuf}; pub(crate) const VISUAL_BINDING_TRANSPARENT_MARKER_RGBA: [u8; 4] = [255, 0, 255, 255]; +const MAX_PROCESSED_IMAGE_BYTES: usize = 64 * 1024 * 1024; +const MAX_PROCESSED_IMAGE_DIMENSION: u32 = 2880; pub(crate) async fn preprocess_for_visual_binding( processed_url: String, @@ -29,6 +31,21 @@ fn preprocess_for_visual_binding_blocking( let bytes = base64::engine::general_purpose::STANDARD .decode(encoded.trim()) .map_err(|error| format!("解析处理图失败:{error}"))?; + if bytes.len() > MAX_PROCESSED_IMAGE_BYTES { + return Err(format!( + "处理图超过 {} MiB 字节上限", + MAX_PROCESSED_IMAGE_BYTES / 1024 / 1024 + )); + } + let dimensions = ImageReader::new(Cursor::new(&bytes)) + .with_guessed_format() + .map_err(|error| format!("解析处理图格式失败:{error}"))? + .into_dimensions() + .map_err(|error| format!("读取处理图尺寸失败:{error}"))?; + if dimensions.0 > MAX_PROCESSED_IMAGE_DIMENSION || dimensions.1 > MAX_PROCESSED_IMAGE_DIMENSION + { + return Err("处理图尺寸超出上限".to_string()); + } let mut image = image::load_from_memory(&bytes) .map_err(|error| format!("解码处理图失败:{error}"))? .to_rgba8();