读取发布图片前先按体积上限失败关闭
- read_draft_image 先看 metadata.len(),超过 8MB(对齐服务端单图上限)直接返回错误 - 避免草稿指向超大本地文件时先把宿主内存读满,再由服务端事后拒绝 - 补稀疏大文件定向测试
This commit is contained in:
@@ -1062,9 +1062,18 @@ fn image_content_type(relative_path: &str) -> Result<&'static str, String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// 单张发布图片的读取上限,与服务端 `MAX_SINGLE_MEDIA_BYTES` 保持一致:先看体积再读,
|
||||
/// 避免草稿指向一个超大本地文件时先把宿主内存顶爆、再由服务端事后拒绝。
|
||||
const MAX_DRAFT_MEDIA_BYTES: u64 = 8 * 1024 * 1024;
|
||||
|
||||
/// 读一张草稿声明的项目内图片:路径先过宿主既有门禁(拒符号链接/越界),再读原始字节。
|
||||
fn read_draft_image(root: &Path, relative_path: &str) -> Result<DraftImage, String> {
|
||||
let absolute = crate::project::resolve_local_project_path(root, relative_path)?;
|
||||
let metadata = std::fs::metadata(&absolute)
|
||||
.map_err(|error| format!("读取发布图片「{relative_path}」失败:{error}"))?;
|
||||
if metadata.len() > MAX_DRAFT_MEDIA_BYTES {
|
||||
return Err(format!("发布图片「{relative_path}」超过 8MB 大小限制"));
|
||||
}
|
||||
let bytes = std::fs::read(&absolute)
|
||||
.map_err(|error| format!("读取发布图片「{relative_path}」失败:{error}"))?;
|
||||
if bytes.is_empty() {
|
||||
@@ -1899,6 +1908,17 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_draft_image_rejects_oversized_files_before_reading() {
|
||||
let root = fixture_root("oversized");
|
||||
let file = std::fs::File::create(root.join("huge.png")).unwrap();
|
||||
file.set_len(MAX_DRAFT_MEDIA_BYTES + 1).unwrap();
|
||||
drop(file);
|
||||
|
||||
let error = read_draft_image(&root, "huge.png").expect_err("must reject oversized media");
|
||||
assert!(error.contains("超过 8MB"), "{error}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_publish_media_reads_local_cover_and_screenshots_from_the_draft() {
|
||||
let root = fixture_root("local");
|
||||
|
||||
Reference in New Issue
Block a user