Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
some tests, at least checking all chunks in all AFL data doesn't pani…
…c it.
- Loading branch information
Showing
4 changed files
with
83 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
/target | ||
Cargo.lock | ||
tests/png |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 not shown.