Merge PR #3015: Never crash: an oversize export size is an error, not a multiply overflow

crates/engine/src/media.rs: main moved render_now and export_job to media/session.rs; the two size checks ported there
crates/engine/src/tests_export.rs: the test is appended to tests/export.rs
This commit is contained in:
aiongg
2026-10-31 02:08:30 +00:00
4 changed files with 34 additions and 1 deletions
+2
View File
@@ -399,6 +399,7 @@ impl crate::Session {
/// Synchronous render (CLI, MCP, tests).
pub fn render_now(&mut self, id: PhotoId, max_w: usize, max_h: usize) -> Result<Rendered, String> {
lightcraft_pipeline::check_output_size(max_w, max_h)?;
let job = self.render_job(id, max_w, max_h, false, true).ok_or("no such photo")?;
let r = job.run();
self.accept(&r);
@@ -429,6 +430,7 @@ impl crate::Session {
space: lightcraft_pipeline::OutputSpace,
depth: lightcraft_pipeline::OutputDepth,
) -> Result<RenderJob, String> {
lightcraft_pipeline::check_output_size(max_w, max_h)?;
let mut job = self.render_job(id, max_w, max_h, false, true).ok_or("no such photo")?;
// An export renders the full image: never a thumbnail's source developed from a smaller copy of the raw
// image that the file keeps (Lightroom's merged DNGs)
+13
View File
@@ -1396,3 +1396,16 @@ fn sixteen_bit_zip_tiff_export_is_never_larger_than_uncompressed() {
eprintln!("demo photo, 16-bit TIFF: none {none} B, ZIP {zip} B, LZW {lzw} B");
assert!(zip <= none, "16-bit ZIP {zip} B is larger than uncompressed {none} B");
}
/// An absurd export size is refused, not a multiply overflow (it panicked before the fix).
#[test]
fn huge_export_size_is_an_error() {
use lightcraft_pipeline::{OutputDepth, OutputSpace};
let mut s = Session::with_demo();
let id = s.active().unwrap();
let huge = usize::MAX >> 8;
assert!(s.render_export(id, huge, huge, OutputSpace::Srgb, OutputDepth::U8).is_err());
assert!(s.render_export(id, 70_000, 10, OutputSpace::Srgb, OutputDepth::U8).is_err());
assert!(s.render_now(id, huge, huge).is_err());
assert!(s.render_now(id, 10, 70_000).is_err());
}