Skip to content

Commit

Permalink
some tests, at least checking all chunks in all AFL data doesn't pani…
Browse files Browse the repository at this point in the history
…c it.
  • Loading branch information
Lokathor committed Dec 5, 2021
1 parent 2322b76 commit 984b185
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,2 +1,3 @@
/target
Cargo.lock
tests/png
2 changes: 1 addition & 1 deletion examples/demo.rs
Expand Up @@ -103,7 +103,7 @@ fn parse_me_a_png_yo(png: &[u8]) -> Result<(Vec<RGBA8>, 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
Expand Down
82 changes: 81 additions & 1 deletion 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<Path>, 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<u8> = 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
});
}
Binary file removed tests/glider-big-rainbow.png
Binary file not shown.

0 comments on commit 984b185

Please sign in to comment.