From 822e89bdc0a3516ab68acd8d59d0a411dc1e4d99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Thu, 1 Oct 2026 14:00:03 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E6=88=90=E5=9B=BE=E7=89=87=E7=9A=84?= =?UTF-8?q?=20gridX/gridY=20=E8=A7=A3=E6=9E=90=E4=B8=8D=E5=86=8D=E6=8A=8A?= =?UTF-8?q?=E8=B6=85=E5=A4=A7=E6=95=B4=E6=95=B0=E6=88=AA=E6=96=AD=E6=88=90?= =?UTF-8?q?=E5=90=88=E6=B3=95=E7=BD=91=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - generate_image_grid_axis 原来用 `value as u32`,u64 直接截断:4294967297(2^32+1)会变成 1,随后 1..=32 的区间校验把这个巨大输入当成合法网格静默接受 - 改成 u32::try_from,超出 u32 的值直接落到 GridAxisNotInteger 拒绝分支,不再依赖截断后的值 - 补一条回归测试:gridX=4294967297 必须被拒绝,gridX=4/gridY=4 仍通过 验证:cargo test --bin genarrative-ai-game-creator-shell -- agent::direct_tool_bridge::tests::generate_image_grid_axis_rejects_values_beyond_u32 通过 --- .../src-tauri/src/agent/direct_tool_bridge.rs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) 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| {