限制视觉绑定处理图的解码规模
在解码前限制 base64 字节数并校验图像宽高,避免异常响应造成过量内存分配。
This commit is contained in:
+18
-1
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user