限制素材分离图片的 Base64 解码大小
对源图和服务端处理图在解码前后统一执行 64 MiB 上限检查,避免无界内存分配。
This commit is contained in:
+23
-6
@@ -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<Vec<u8>, 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<RawEditItem>,
|
||||
@@ -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}"))?
|
||||
|
||||
Reference in New Issue
Block a user