Coverage Report

Created: 2026-07-16 07:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/image/fuzz/fuzzers/fuzzer_script_exr.rs
Line
Count
Source
1
#![no_main]
2
#[macro_use]
3
extern crate libfuzzer_sys;
4
extern crate image;
5
6
use image::codecs::openexr::*;
7
use image::ExtendedColorType;
8
use image::ImageDecoder;
9
use image::ImageEncoder;
10
use image::ImageResult;
11
use image::Limits;
12
use std::io::{BufRead, Cursor, Seek, Write};
13
14
// "just dont panic"
15
2.01k
fn roundtrip(bytes: &[u8]) -> ImageResult<()> {
16
    /// Read the file from the specified path into an `Rgba32FImage`.
17
    // TODO this method should probably already exist in the main image crate
18
2.09k
    fn read_as_rgba_byte_image(read: impl BufRead + Seek) -> ImageResult<(u32, u32, Vec<u8>)> {
19
2.09k
        let mut decoder = OpenExrDecoder::with_alpha_preference(read, Some(true))?;
20
887
        let prep = decoder.prepare_image()?;
21
887
        match usize::try_from(prep.total_bytes()) {
22
887
            Ok(decoded_size) if decoded_size <= 256 * 1024 * 1024 => {
23
874
                decoder.set_limits(Limits::default())?;
24
874
                let (width, height) = prep.layout.dimensions();
25
874
                let mut buffer = vec![0; decoded_size];
26
874
                decoder.read_image(buffer.as_mut_slice())?;
27
166
                Ok((width, height, buffer))
28
            }
29
13
            _ => Err(image::ImageError::Limits(
30
13
                image::error::LimitError::from_kind(
31
13
                    image::error::LimitErrorKind::InsufficientMemory,
32
13
                ),
33
13
            )),
34
        }
35
2.09k
    }
fuzzer_script_exr::roundtrip::read_as_rgba_byte_image::<std::io::cursor::Cursor<alloc::vec::Vec<u8>>>
Line
Count
Source
18
83
    fn read_as_rgba_byte_image(read: impl BufRead + Seek) -> ImageResult<(u32, u32, Vec<u8>)> {
19
83
        let mut decoder = OpenExrDecoder::with_alpha_preference(read, Some(true))?;
20
83
        let prep = decoder.prepare_image()?;
21
83
        match usize::try_from(prep.total_bytes()) {
22
83
            Ok(decoded_size) if decoded_size <= 256 * 1024 * 1024 => {
23
83
                decoder.set_limits(Limits::default())?;
24
83
                let (width, height) = prep.layout.dimensions();
25
83
                let mut buffer = vec![0; decoded_size];
26
83
                decoder.read_image(buffer.as_mut_slice())?;
27
83
                Ok((width, height, buffer))
28
            }
29
0
            _ => Err(image::ImageError::Limits(
30
0
                image::error::LimitError::from_kind(
31
0
                    image::error::LimitErrorKind::InsufficientMemory,
32
0
                ),
33
0
            )),
34
        }
35
83
    }
fuzzer_script_exr::roundtrip::read_as_rgba_byte_image::<std::io::cursor::Cursor<&[u8]>>
Line
Count
Source
18
2.01k
    fn read_as_rgba_byte_image(read: impl BufRead + Seek) -> ImageResult<(u32, u32, Vec<u8>)> {
19
2.01k
        let mut decoder = OpenExrDecoder::with_alpha_preference(read, Some(true))?;
20
804
        let prep = decoder.prepare_image()?;
21
804
        match usize::try_from(prep.total_bytes()) {
22
804
            Ok(decoded_size) if decoded_size <= 256 * 1024 * 1024 => {
23
791
                decoder.set_limits(Limits::default())?;
24
791
                let (width, height) = prep.layout.dimensions();
25
791
                let mut buffer = vec![0; decoded_size];
26
791
                decoder.read_image(buffer.as_mut_slice())?;
27
83
                Ok((width, height, buffer))
28
            }
29
13
            _ => Err(image::ImageError::Limits(
30
13
                image::error::LimitError::from_kind(
31
13
                    image::error::LimitErrorKind::InsufficientMemory,
32
13
                ),
33
13
            )),
34
        }
35
2.01k
    }
36
37
    /// Write an `Rgba32FImage`.
38
    /// Assumes the writer is buffered. In most cases,
39
    /// you should wrap your writer in a `BufWriter` for best performance.
40
    // TODO this method should probably already exist in the main image crate
41
83
    fn write_rgba_image(
42
83
        write: impl Write + Seek,
43
83
        (width, height, data): &(u32, u32, Vec<u8>),
44
83
    ) -> ImageResult<()> {
45
83
        OpenExrEncoder::new(write).write_image(
46
83
            data.as_slice(),
47
83
            *width,
48
83
            *height,
49
83
            ExtendedColorType::Rgba32F,
50
        )
51
83
    }
52
53
2.01k
    let decoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;
54
55
    #[allow(clippy::disallowed_methods)]
56
83
    let mut bytes = Vec::with_capacity(bytes.len() + 20);
57
83
    write_rgba_image(Cursor::new(&mut bytes), &decoded_image)?;
58
59
83
    let redecoded_image = read_as_rgba_byte_image(Cursor::new(bytes))?;
60
61
    // if both images are valid, assert read/write consistency
62
83
    assert_eq!(
63
        decoded_image, redecoded_image,
64
0
        "image was valid but was not reproducible"
65
    );
66
83
    Ok(())
67
2.01k
}
68
69
fuzz_target!(|data: &[u8]| {
70
    let _img = roundtrip(data); // fixme not optimized away?
71
});