Expose find_new_files_rec
in libafl_bolts::fs
(#2404)
This commit is contained in:
parent
dc93f6c186
commit
4370a84bd2
@ -1,15 +1,13 @@
|
|||||||
//! The [`SyncFromDiskStage`] is a stage that imports inputs from disk for e.g. sync with AFL
|
//! The [`SyncFromDiskStage`] is a stage that imports inputs from disk for e.g. sync with AFL
|
||||||
|
|
||||||
use alloc::borrow::{Cow, ToOwned};
|
use alloc::{
|
||||||
use core::{marker::PhantomData, time::Duration};
|
borrow::{Cow, ToOwned},
|
||||||
use std::{
|
|
||||||
fs,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
time::SystemTime,
|
|
||||||
vec::Vec,
|
vec::Vec,
|
||||||
};
|
};
|
||||||
|
use core::{marker::PhantomData, time::Duration};
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use libafl_bolts::{current_time, shmem::ShMemProvider, Named};
|
use libafl_bolts::{current_time, fs::find_new_files_rec, shmem::ShMemProvider, Named};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[cfg(feature = "introspection")]
|
#[cfg(feature = "introspection")]
|
||||||
@ -25,6 +23,9 @@ use crate::{
|
|||||||
Error, HasMetadata, HasNamedMetadata,
|
Error, HasMetadata, HasNamedMetadata,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Default name for `SyncFromDiskStage`; derived from AFL++
|
||||||
|
pub const SYNC_FROM_DISK_STAGE_NAME: &str = "sync";
|
||||||
|
|
||||||
/// Metadata used to store information about disk sync time
|
/// Metadata used to store information about disk sync time
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
any(not(feature = "serdeany_autoreg"), miri),
|
any(not(feature = "serdeany_autoreg"), miri),
|
||||||
@ -51,46 +52,6 @@ impl SyncFromDiskMetadata {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Default name for `SyncFromDiskStage`; derived from AFL++
|
|
||||||
pub const SYNC_FROM_DISK_STAGE_NAME: &str = "sync";
|
|
||||||
|
|
||||||
/// Finds new files in the given directory, taking the last time we looked at this path as parameter.
|
|
||||||
/// This method works recursively.
|
|
||||||
/// If `last` is `None`, it'll load all file.
|
|
||||||
fn find_new_files_rec<P: AsRef<Path>>(
|
|
||||||
dir: P,
|
|
||||||
last_check: &Option<Duration>,
|
|
||||||
) -> Result<Vec<PathBuf>, Error> {
|
|
||||||
let mut new_files = Vec::<PathBuf>::new();
|
|
||||||
for entry in fs::read_dir(dir)? {
|
|
||||||
let entry = entry?;
|
|
||||||
let path = entry.path();
|
|
||||||
let attributes = fs::metadata(&path);
|
|
||||||
|
|
||||||
if attributes.is_err() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let attr = attributes?;
|
|
||||||
|
|
||||||
if attr.is_file() && attr.len() > 0 {
|
|
||||||
if let Ok(time) = attr.modified() {
|
|
||||||
if let Some(last_check) = last_check {
|
|
||||||
if time.duration_since(SystemTime::UNIX_EPOCH).unwrap() < *last_check {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
new_files.push(path.clone());
|
|
||||||
}
|
|
||||||
} else if attr.is_dir() {
|
|
||||||
let dir_left_to_sync = find_new_files_rec(&entry.path(), last_check)?;
|
|
||||||
new_files.extend(dir_left_to_sync);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(new_files)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
|
/// A stage that loads testcases from disk to sync with other fuzzers such as AFL++
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SyncFromDiskStage<CB, E, EM, Z> {
|
pub struct SyncFromDiskStage<CB, E, EM, Z> {
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
//! `LibAFL` functionality for filesystem interaction
|
//! `LibAFL` functionality for filesystem interaction
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
use alloc::borrow::ToOwned;
|
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use alloc::{borrow::ToOwned, vec::Vec};
|
||||||
use core::cell::RefCell;
|
use core::cell::RefCell;
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use core::time::Duration;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use std::os::unix::prelude::{AsRawFd, RawFd};
|
use std::os::unix::prelude::{AsRawFd, RawFd};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use std::time::SystemTime;
|
||||||
use std::{
|
use std::{
|
||||||
fs::{self, remove_file, File, OpenOptions},
|
fs::{self, remove_file, File, OpenOptions},
|
||||||
io::{Seek, Write},
|
io::{Seek, Write},
|
||||||
@ -140,6 +144,44 @@ impl InputFile {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Finds new files in the given directory, taking the last time we looked at this path as parameter.
|
||||||
|
/// This method works recursively.
|
||||||
|
/// If `last` is `None`, it'll load all file.
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub fn find_new_files_rec<P: AsRef<Path>>(
|
||||||
|
dir: P,
|
||||||
|
last_check: &Option<Duration>,
|
||||||
|
) -> Result<Vec<PathBuf>, Error> {
|
||||||
|
let mut new_files = Vec::<PathBuf>::new();
|
||||||
|
for entry in fs::read_dir(dir)? {
|
||||||
|
let entry = entry?;
|
||||||
|
let path = entry.path();
|
||||||
|
let attributes = fs::metadata(&path);
|
||||||
|
|
||||||
|
if attributes.is_err() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let attr = attributes?;
|
||||||
|
|
||||||
|
if attr.is_file() && attr.len() > 0 {
|
||||||
|
if let Ok(time) = attr.modified() {
|
||||||
|
if let Some(last_check) = last_check {
|
||||||
|
if time.duration_since(SystemTime::UNIX_EPOCH).unwrap() < *last_check {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new_files.push(path.clone());
|
||||||
|
}
|
||||||
|
} else if attr.is_dir() {
|
||||||
|
let dir_left_to_sync = find_new_files_rec(entry.path(), last_check)?;
|
||||||
|
new_files.extend(dir_left_to_sync);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(new_files)
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl Drop for InputFile {
|
impl Drop for InputFile {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user