From 984b18511bc4ee3f62ca13e494c518b18f403d80 Mon Sep 17 00:00:00 2001 From: Lokathor Date: Sun, 5 Dec 2021 14:12:07 -0700 Subject: [PATCH] some tests, at least checking all chunks in all AFL data doesn't panic it. --- .gitignore | 1 + examples/demo.rs | 2 +- tests/all_tests.rs | 82 ++++++++++++++++++++++++++++++++++- tests/glider-big-rainbow.png | Bin 1692 -> 0 bytes 4 files changed, 83 insertions(+), 2 deletions(-) delete mode 100644 tests/glider-big-rainbow.png diff --git a/.gitignore b/.gitignore index 96ef6c0b..f49efebe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target Cargo.lock +tests/png diff --git a/examples/demo.rs b/examples/demo.rs index b5bf8598..f0715c53 100644 --- a/examples/demo.rs +++ b/examples/demo.rs @@ -103,7 +103,7 @@ fn parse_me_a_png_yo(png: &[u8]) -> Result<(Vec, u32, u32), PngError> { decompress_idat_to_temp_storage(&mut temp_memory_buffer, idat_slice_it)?; // let mut final_storage = Vec::new(); - final_storage.resize((ihdr.width * ihdr.height) as usize, RGBA8::default()); + final_storage.resize((ihdr.width.saturating_mul(ihdr.height)) as usize, RGBA8::default()); // match ihdr.pixel_format { // we already have all four channels diff --git a/tests/all_tests.rs b/tests/all_tests.rs index bc0feed5..d1cac1fd 100644 --- a/tests/all_tests.rs +++ b/tests/all_tests.rs @@ -1 +1,81 @@ -//const GLIDER_BIG_RAINBOW: &[u8] = include_bytes!("glider-big-rainbow.png"); +use std::path::{Path, PathBuf}; + +use imagine::png::{critical_errors_only, PngChunk, RawPngChunkIter}; + +/// Recursively walks over the `path` given, which must be a directory. +/// +/// Your `op` is passed a [`PathBuf`] for each file found. +/// +/// ## Panics +/// * If the path given is not a directory. +pub fn recursive_read_dir(path: impl AsRef, mut op: impl FnMut(PathBuf)) { + use std::collections::VecDeque; + // + let path = path.as_ref(); + assert!(path.is_dir()); + // Note(Lokathor): Being *literally* recursive can blow out the stack for no + // reason. Instead, we use a queue based system. Each loop pulls a dir out of + // the queue and walks it. + // * If we find a sub-directory that goes into the queue for later. + // * Files get passed to the `op` + // * Symlinks we check if they point to a Dir or File and act accordingly. + // + // REMINDER: if a symlink makes a loop on the file system then this will trap + // us in an endless loop. That's the user's fault! + let mut path_q = VecDeque::new(); + path_q.push_back(PathBuf::from(path)); + while let Some(path_buf) = path_q.pop_front() { + match std::fs::read_dir(&path_buf) { + Err(e) => eprintln!("Can't read_dir {path}: {e}", path = path_buf.display(), e = e), + Ok(read_dir) => { + for result_dir_entry in read_dir { + match result_dir_entry { + Err(e) => eprintln!("Error with dir entry: {e}", e = e), + Ok(dir_entry) => match dir_entry.file_type() { + Ok(ft) if ft.is_dir() => path_q.push_back(dir_entry.path()), + Ok(ft) if ft.is_file() => op(dir_entry.path()), + Ok(ft) if ft.is_symlink() => match dir_entry.metadata() { + Ok(metadata) if metadata.is_dir() => path_q.push_back(dir_entry.path()), + Ok(metadata) if metadata.is_file() => op(dir_entry.path()), + Err(e) => eprintln!( + "Can't get metadata for symlink {path}: {e}", + path = dir_entry.path().display(), + e = e + ), + _ => eprintln!( + "Found symlink {path} but it's not a file or a directory.", + path = dir_entry.path().display() + ), + }, + Err(e) => eprintln!( + "Can't get file type of {path}: {e}", + path = dir_entry.path().display(), + e = e + ), + _ => eprintln!( + "Found dir_entry {path} but it's not a file, directory, or symlink.", + path = dir_entry.path().display() + ), + }, + } + } + } + } + } +} + +#[test] +fn afl_images_no_panic() { + let png_folder = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests").join("png"); + recursive_read_dir(png_folder, |path_buf| { + println!("using file `{path_buf}`", path_buf = path_buf.display()); + // right now we just walk the chunks. + let png: Vec = std::fs::read(path_buf.as_path()).unwrap(); + RawPngChunkIter::new(&png) + .map(PngChunk::try_from) + .filter(critical_errors_only) + .for_each(|_| ()); + + // TODO: use the chunks + }); +} diff --git a/tests/glider-big-rainbow.png b/tests/glider-big-rainbow.png deleted file mode 100644 index cfdedafc691b3867f79effced342ae73fcb4c920..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1692 zcmeAS@N?(olHy`uVBq!ia0y~yV4MKL9Be?5hW%z|fD~hKkh>GZx^prwfgF}}M_)$< zhK>E)e-c@Ne1&9>AYTTCDm9?;76yi2AZ;%g7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a z5n0T@z;^_M8K-LVNi#68v3j~VhE&A8y}dDzDNw>K@LHYETSlz{Hm(iar8$Qp60Wdy zyg8)yhKVweD~9cf)`me zj1S^jSQ=a$7(7O)p%w(ozSeA(muB#L#>A)~D8L}Zh)&J?W`FD%Q?A(UjeXH?rzIEm z{j2#ud-=u(6SzmCd{8I%l&JIOzc(^INYTR