Add selectable metadata format, including postcard and JSON (#59)

* Add selectable metadata format, including postcard and JSON

* Formatting

* nostd fix
This commit is contained in:
s1341 2021-04-23 18:25:00 +03:00 committed by GitHub
parent c2efea2f93
commit fc8056214b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 8 deletions

View File

@ -9,6 +9,18 @@ use std::{fs, fs::File, io::Write, path::PathBuf};
use crate::{corpus::Corpus, corpus::Testcase, inputs::Input, state::HasMetadata, Error};
/// Options for the the format of the on-disk metadata
#[cfg(feature = "std")]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum OnDiskMetadataFormat {
/// A binary-encoded postcard
Postcard,
/// JSON
Json,
/// JSON formatted for readability
JsonPretty,
}
/// A corpus able to store testcases to disk, and load them from disk, when they are being used.
#[cfg(feature = "std")]
#[derive(Default, Serialize, Deserialize, Clone, Debug)]
@ -20,7 +32,7 @@ where
entries: Vec<RefCell<Testcase<I>>>,
current: Option<usize>,
dir_path: PathBuf,
save_meta: bool,
meta_format: Option<OnDiskMetadataFormat>,
}
impl<I> Corpus<I> for OnDiskCorpus<I>
@ -42,11 +54,15 @@ where
let filename_str = filename.to_str().expect("Invalid Path");
testcase.set_filename(filename_str.into());
};
if self.save_meta {
if self.meta_format.is_some() {
let filename = testcase.filename().as_ref().unwrap().to_owned() + ".metadata";
let mut file = File::create(filename)?;
// TODO maybe use JSON
let serialized = postcard::to_allocvec(testcase.metadata())?;
let serialized = match self.meta_format.as_ref().unwrap() {
OnDiskMetadataFormat::Postcard => postcard::to_allocvec(testcase.metadata())?,
OnDiskMetadataFormat::Json => serde_json::to_vec(testcase.metadata())?,
OnDiskMetadataFormat::JsonPretty => serde_json::to_vec_pretty(testcase.metadata())?,
};
file.write_all(&serialized)?;
}
testcase
@ -107,19 +123,22 @@ where
entries: vec![],
current: None,
dir_path,
save_meta: false,
meta_format: None,
})
}
/// Creates the OnDiskCorpus specifying if metatada must be saved to disk.
/// Creates the OnDiskCorpus specifying the type of metatada to be saved to disk.
/// Will error, if `std::fs::create_dir_all` failed for `dir_path`.
pub fn new_save_meta(dir_path: PathBuf, save_meta: bool) -> Result<Self, Error> {
pub fn new_save_meta(
dir_path: PathBuf,
meta_format: Option<OnDiskMetadataFormat>,
) -> Result<Self, Error> {
fs::create_dir_all(&dir_path)?;
Ok(Self {
entries: vec![],
current: None,
dir_path,
save_meta,
meta_format,
})
}
}

View File

@ -100,6 +100,14 @@ impl From<postcard::Error> for Error {
}
}
/// Stringify the json serializer error
#[cfg(feature = "std")]
impl From<serde_json::Error> for Error {
fn from(err: serde_json::Error) -> Self {
Self::Serialize(format!("{:?}", err))
}
}
/// Create an AFL Error from io Error
#[cfg(feature = "std")]
impl From<io::Error> for Error {