diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs index 2bf34446b..b14d8eb13 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs @@ -2850,7 +2850,8 @@ fn generate_image_grid_axis( }; value .as_u64() - .map(|value| Some(value as u32)) + .and_then(|value| u32::try_from(value).ok()) + .map(Some) .ok_or(GenerateImageError::GridAxisNotInteger { axis }) } @@ -4772,6 +4773,30 @@ mod tests { .is_err()); } + #[test] + fn generate_image_grid_axis_rejects_values_beyond_u32() { + let error = match generate_image_input(&json!({ + "prompt": "像素风图标集", + "kind": "icon-spritesheet", + "sliceMode": "grid", + "gridX": 4_294_967_297_u64, + "gridY": 1 + })) { + Ok(_) => panic!("gridX 超过 u32 时不得截断成合法网格"), + Err(error) => error, + } + .to_user_msg(); + assert!(error.contains("gridX"), "{error}"); + assert!(generate_image_input(&json!({ + "prompt": "像素风图标集", + "kind": "icon-spritesheet", + "sliceMode": "grid", + "gridX": 4, + "gridY": 4 + })) + .is_ok()); + } + #[test] fn large_mcp_images_are_reduced_to_bounded_jpeg_previews() { let image = image::RgbaImage::from_fn(1600, 1200, |x, y| {