Add RefCellValueObserver (#1363)
* add RefCellValueObserver * appease the clippy gods * Update libafl/src/observers/value.rs Co-authored-by: Langston Barrett <langston.barrett@gmail.com> --------- Co-authored-by: Langston Barrett <langston.barrett@gmail.com>
This commit is contained in:
parent
a95b322b1c
commit
f76331eac7
@ -5,8 +5,10 @@ use alloc::{
|
|||||||
string::{String, ToString},
|
string::{String, ToString},
|
||||||
};
|
};
|
||||||
use core::{
|
use core::{
|
||||||
|
cell::{Ref, RefCell},
|
||||||
fmt::Debug,
|
fmt::Debug,
|
||||||
hash::{BuildHasher, Hash, Hasher},
|
hash::{BuildHasher, Hash, Hasher},
|
||||||
|
ops::Deref,
|
||||||
};
|
};
|
||||||
|
|
||||||
use ahash::RandomState;
|
use ahash::RandomState;
|
||||||
@ -22,9 +24,8 @@ use crate::{
|
|||||||
|
|
||||||
/// A simple observer with a single value.
|
/// A simple observer with a single value.
|
||||||
///
|
///
|
||||||
/// The intent is that the value is something with interior mutability (e.g., a
|
/// The intent is that the value is something with interior mutability which the target could write to even though this
|
||||||
/// `RefCell`), which the target could write to even though this observer has a
|
/// observer has a reference to it. Use [`RefCellValueObserver`] if using a [`RefCell`] around the value.
|
||||||
/// reference to it.
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
||||||
pub struct ValueObserver<'a, T>
|
pub struct ValueObserver<'a, T>
|
||||||
@ -104,3 +105,87 @@ where
|
|||||||
Some(s.finish())
|
Some(s.finish())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A simple observer with a single [`RefCell`]'d value.
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(bound = "T: serde::de::DeserializeOwned")]
|
||||||
|
pub struct RefCellValueObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize,
|
||||||
|
{
|
||||||
|
/// The name of this observer.
|
||||||
|
name: String,
|
||||||
|
/// The value.
|
||||||
|
pub value: OwnedRef<'a, RefCell<T>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> RefCellValueObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
/// Creates a new [`RefCellValueObserver`] with the given name.
|
||||||
|
#[must_use]
|
||||||
|
pub fn new(name: &'static str, value: &'a RefCell<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
name: name.to_string(),
|
||||||
|
value: OwnedRef::Ref(value),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a reference to the underlying value.
|
||||||
|
#[must_use]
|
||||||
|
pub fn get_ref<'b>(&'b self) -> Ref<'a, T>
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
|
self.value.as_ref().borrow()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the value.
|
||||||
|
pub fn set(&mut self, new_value: T) {
|
||||||
|
self.value.as_ref().replace(new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clone or move the current value out of this object.
|
||||||
|
#[must_use]
|
||||||
|
pub fn take(self) -> T
|
||||||
|
where
|
||||||
|
T: Clone,
|
||||||
|
{
|
||||||
|
match self.value {
|
||||||
|
OwnedRef::Ref(r) => r.borrow().deref().clone(),
|
||||||
|
OwnedRef::Owned(v) => v.borrow().clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This *does not* reset the value inside the observer.
|
||||||
|
impl<'a, S, T> Observer<S> for RefCellValueObserver<'a, T>
|
||||||
|
where
|
||||||
|
S: UsesInput,
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn pre_exec(&mut self, _state: &mut S, _input: &S::Input) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T> Named for RefCellValueObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, T: Hash> ObserverWithHashField for RefCellValueObserver<'a, T>
|
||||||
|
where
|
||||||
|
T: Debug + Serialize + serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
fn hash(&self) -> Option<u64> {
|
||||||
|
let mut s = RandomState::with_seeds(1, 2, 3, 4).build_hasher();
|
||||||
|
self.value.as_ref().borrow().hash(&mut s);
|
||||||
|
Some(s.finish())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user