Apply image preview limits to detected format instead of extension
This commit is contained in:
1 parent
6ed3366d03
commit
4b0b5ebfd9
2 files changed
+40
-11
No files matched your search
@@ -342,6 +342,14 @@ fn validated_result(index: &SearchIndex, path: &str) -> Result<PathBuf, String>
|
||||
Ok(canonical)
|
||||
}
|
||||
|
||||
fn preview_pixel_limit(format: Option<image::ImageFormat>) -> u64 {
|
||||
if format == Some(image::ImageFormat::Jpeg) {
|
||||
64 * 1024 * 1024
|
||||
} else {
|
||||
16 * 1024 * 1024
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct MediaPreview {
|
||||
path: String,
|
||||
@@ -373,21 +381,15 @@ async fn prepare_media_preview(
|
||||
if bytes > 64 * 1024 * 1024 {
|
||||
return Err("Image exceeds the 64 MiB preview limit.".into());
|
||||
}
|
||||
let (width, height) = image::ImageReader::open(&canonical)
|
||||
let reader = image::ImageReader::open(&canonical)
|
||||
.map_err(|error| error.to_string())?
|
||||
.with_guessed_format()
|
||||
.map_err(|error| error.to_string())?
|
||||
.map_err(|error| error.to_string())?;
|
||||
// Resource limits follow decoded format, not a renameable suffix.
|
||||
let max_pixels = preview_pixel_limit(reader.format());
|
||||
let (width, height) = reader
|
||||
.into_dimensions()
|
||||
.map_err(|error| format!("Image preview is unavailable: {error}"))?;
|
||||
let jpeg = canonical
|
||||
.extension()
|
||||
.and_then(|value| value.to_str())
|
||||
.is_some_and(|value| matches!(value.to_ascii_lowercase().as_str(), "jpg" | "jpeg"));
|
||||
let max_pixels = if jpeg {
|
||||
64 * 1024 * 1024
|
||||
} else {
|
||||
16 * 1024 * 1024
|
||||
};
|
||||
if width == 0 || height == 0 || u64::from(width) * u64::from(height) > max_pixels {
|
||||
return Err("Image exceeds the supported preview dimensions.".into());
|
||||
}
|
||||
@@ -809,4 +811,26 @@ mod tests {
|
||||
assert!(validated_result(&index, &indexed.to_string_lossy()).is_err());
|
||||
assert!(validated_result(&index, &root.path().to_string_lossy()).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn renamed_png_cannot_receive_the_larger_jpeg_preview_budget() {
|
||||
let root = tempfile::tempdir().unwrap();
|
||||
let path = root.path().join("misnamed.jpg");
|
||||
let image = image::GrayImage::new(4097, 4096);
|
||||
image
|
||||
.save_with_format(&path, image::ImageFormat::Png)
|
||||
.unwrap();
|
||||
let reader = image::ImageReader::open(&path)
|
||||
.unwrap()
|
||||
.with_guessed_format()
|
||||
.unwrap();
|
||||
assert_eq!(reader.format(), Some(image::ImageFormat::Png));
|
||||
let limit = preview_pixel_limit(reader.format());
|
||||
let (width, height) = reader.into_dimensions().unwrap();
|
||||
assert!(u64::from(width) * u64::from(height) > limit);
|
||||
assert!(
|
||||
u64::from(width) * u64::from(height)
|
||||
< preview_pixel_limit(Some(image::ImageFormat::Jpeg))
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user