From f7edc9d0eed88632f03b1cadbe770950b5e8692f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Wed, 9 Sep 2026 11:04:44 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8C=BA=E5=88=86=20Raw=20=E5=9B=BE=E7=89=87?= =?UTF-8?q?=20PNG=20=E8=B5=84=E6=BA=90=E9=99=90=E5=88=B6=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将有效但超出解码限制的 PNG 映射为明确的 400 提示 补充超大合法 PNG 的回归测试 --- server-rs/crates/api-server/src/raw_image.rs | 32 +++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/server-rs/crates/api-server/src/raw_image.rs b/server-rs/crates/api-server/src/raw_image.rs index 2023ecec8..cea19316c 100644 --- a/server-rs/crates/api-server/src/raw_image.rs +++ b/server-rs/crates/api-server/src/raw_image.rs @@ -243,7 +243,7 @@ fn decode_image(value: RawImageData, field: &str) -> Result Result AppError { + let message = match error { + image::ImageError::Limits(_) => { + format!("{field}.data 超出 PNG 尺寸或解码资源上限(单边不超过 {RAW_IMAGE_MAX_EDGE}px)") + } + _ => format!("{field}.data 必须是有效 PNG 文件"), + }; + bad_request(message) +} + async fn raw_image_edit_price(state: &AppState, width: u32, height: u32) -> Result { let tier = if width.max(height) > 1536 { "2K" } else { "1K" }; state @@ -373,4 +383,24 @@ mod tests { assert!(prepare_request(serde_json::from_value(payload).expect("request")).is_err()); } } + + #[test] + fn oversized_valid_png_reports_resource_limit() { + let payload = serde_json::json!({ + "image": { + "data": encoded_png(RAW_IMAGE_MAX_EDGE + 1, 1), + "mimeType": "image/png" + }, + "prompt": "edit", + "width": 1024, + "height": 1024 + }); + let parsed: RawImageEditRequest = serde_json::from_value(payload).expect("request"); + let error = match prepare_request(parsed) { + Ok(_) => panic!("oversized PNG should fail"), + Err(error) => error, + }; + + assert!(format!("{error:?}").contains("超出 PNG 尺寸或解码资源上限")); + } }