testcase clone()

This commit is contained in:
Andrea Fioraldi 2020-11-27 18:30:44 +01:00
parent e1779e4503
commit 91ab778f9e
3 changed files with 46 additions and 17 deletions

View File

@ -22,10 +22,33 @@ use crate::AflError;
pub trait TestcaseMetadata: Any {
/// The name of this metadata - used to find it in the list of avaliable metadatas
fn name(&self) -> &'static str;
fn clone(&self) -> Box<dyn TestcaseMetadata>;
}
/// Just a wrapper of Boxed TestcaseMetadata trait object for Clone
#[derive(Serialize, Deserialize)]
pub struct TestcaseMetadataContainer {
meta: Box<dyn TestcaseMetadata>,
}
impl Clone for TestcaseMetadataContainer {
fn clone(&self) -> Self {
TestcaseMetadataContainer {
meta: self.meta.clone(),
}
}
}
impl TestcaseMetadataContainer {
pub fn meta(&self) -> &Box<dyn TestcaseMetadata> {
&self.meta
}
pub fn meta_mut(&mut self) -> &mut Box<dyn TestcaseMetadata> {
&mut self.meta
}
}
/// An entry in the Testcase Corpus
#[derive(Default, Serialize, Deserialize)]
#[derive(Default, Clone, Serialize, Deserialize)]
pub struct Testcase<I>
where
I: Input,
@ -36,8 +59,9 @@ where
filename: Option<String>,
/// Accumulated fitness from all the feedbacks
fitness: u32,
// TODO find a way to use TypeId
/// Map of metadatas associated with this testcase
metadatas: HashMap<String, Box<dyn TestcaseMetadata>>,
metadatas: HashMap<String, TestcaseMetadataContainer>,
}
impl<I> Into<Rc<RefCell<Self>>> for Testcase<I>
@ -100,12 +124,20 @@ where
}
/// Get all the metadatas into an HashMap (mutable)
pub fn metadatas(&mut self) -> &mut HashMap<String, Box<dyn TestcaseMetadata>> {
pub fn metadatas(&mut self) -> &mut HashMap<String, TestcaseMetadataContainer> {
&mut self.metadatas
}
/// Add a metadata
pub fn add_metadata(&mut self, meta: Box<dyn TestcaseMetadata>) {
self.metadatas.insert(meta.name().to_string(), meta);
pub fn add_metadata<TM>(&mut self, meta: TM)
where
TM: TestcaseMetadata + 'static,
{
self.metadatas.insert(
meta.name().to_string(),
TestcaseMetadataContainer {
meta: Box::new(meta),
},
);
}
/// Create a new Testcase instace given an input

View File

@ -214,22 +214,17 @@ where
}
fn handle_in_client(
&mut self,
&self,
/*client: &dyn EventManager<S, C, E, I, R>,*/ _state: &mut S,
corpus: &mut C,
) -> Result<(), AflError> {
match std::mem::replace(
self,
Event::None {
phantom: PhantomData,
},
) {
match self {
Event::NewTestcase {
sender_id: _,
testcase,
phantom: _,
} => {
corpus.add(testcase);
corpus.add(testcase.clone());
Ok(())
}
_ => Err(AflError::Unknown(
@ -322,7 +317,7 @@ where
}
handled
.iter()
.zip(self.events.iter_mut())
.zip(self.events.iter())
.map(|(x, event)| match x {
BrokerEventResult::Forward => event.handle_in_client(state, corpus),
// Ignore broker-only events

View File

@ -176,6 +176,10 @@ impl TestcaseMetadata for MapNoveltiesMetadata {
fn name(&self) -> &'static str {
"MapNoveltiesMetadata"
}
fn clone(&self) -> Box<dyn TestcaseMetadata> {
Box::new(MapNoveltiesMetadata::new(self.novelties.clone()))
}
}
impl MapNoveltiesMetadata {
pub fn novelties(&self) -> &[usize] {
@ -235,9 +239,7 @@ where
}
fn append_metadata(&mut self, testcase: &mut Testcase<I>) -> Result<(), AflError> {
let meta = Box::new(MapNoveltiesMetadata::new(core::mem::take(
&mut self.novelties,
)));
let meta = MapNoveltiesMetadata::new(core::mem::take(&mut self.novelties));
testcase.add_metadata(meta);
Ok(())
}