feat: add decode_comprehensive fuzz target with safe metadata probing
New fuzz target exercises TiffHeader::parse, dimensions/colortype probing, chunk-by-chunk reading, and multi-IFD iteration. Guards get_chunk_type/chunk_dimensions behind dimensions() success check to avoid documented panics on non-image IFDs.
This commit is contained in:
1 parent
032421634f
commit
ea6e2a8d80
2 files changed
+56
No files matched your search
@@ -23,3 +23,9 @@ name = "decode_image"
|
|||||||
path = "fuzz_targets/decode_image.rs"
|
path = "fuzz_targets/decode_image.rs"
|
||||||
test = false
|
test = false
|
||||||
doc = false
|
doc = false
|
||||||
|
|
||||||
|
[[bin]]
|
||||||
|
name = "decode_comprehensive"
|
||||||
|
path = "fuzz_targets/decode_comprehensive.rs"
|
||||||
|
test = false
|
||||||
|
doc = false
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#![no_main]
|
||||||
|
use libfuzzer_sys::fuzz_target;
|
||||||
|
|
||||||
|
fuzz_target!(|data: &[u8]| {
|
||||||
|
let cursor = std::io::Cursor::new(data);
|
||||||
|
|
||||||
|
// Path 1: TiffHeader::parse (probe)
|
||||||
|
{
|
||||||
|
let _ = tiff::decoder::TiffHeader::parse(std::io::Cursor::new(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path 2: Full decode with strict limits
|
||||||
|
let mut decoder = match tiff::decoder::Decoder::open(cursor) {
|
||||||
|
Ok(d) => d,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut limits = tiff::decoder::Limits::default();
|
||||||
|
limits.decoding_buffer_size = 512 * 1024;
|
||||||
|
limits.ifd_value_size = 64 * 1024;
|
||||||
|
limits.intermediate_buffer_size = 512 * 1024;
|
||||||
|
|
||||||
|
decoder = decoder.with_limits(limits);
|
||||||
|
|
||||||
|
// Probe metadata — dimensions() triggers image validation,
|
||||||
|
// must succeed before get_chunk_type/chunk_dimensions (they unwrap image)
|
||||||
|
let dims_ok = decoder.dimensions().is_ok();
|
||||||
|
let _ = decoder.colortype();
|
||||||
|
if dims_ok {
|
||||||
|
let _ = decoder.get_chunk_type();
|
||||||
|
let _ = decoder.chunk_dimensions();
|
||||||
|
}
|
||||||
|
let _ = decoder.more_images();
|
||||||
|
|
||||||
|
// Read chunks individually if available
|
||||||
|
let _ = decoder.read_chunk(0);
|
||||||
|
|
||||||
|
// Read full image
|
||||||
|
let _ = decoder.read_image();
|
||||||
|
|
||||||
|
// Iterate through all IFDs
|
||||||
|
while decoder.more_images() {
|
||||||
|
if decoder.next_image().is_err() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let _ = decoder.dimensions();
|
||||||
|
let _ = decoder.colortype();
|
||||||
|
let _ = decoder.read_image();
|
||||||
|
}
|
||||||
|
});
|
||||||
Reference in new issue
Block a user