use alloc::{borrow::Cow, boxed::Box, vec::Vec};
use core::{
cell::{Ref, RefCell, RefMut},
fmt::Debug,
hash::{Hash, Hasher},
ops::{Deref, DerefMut},
};
use ahash::RandomState;
use libafl_bolts::{AsIter, AsIterMut, AsSlice, AsSliceMut, HasLen, Named, ownedref::OwnedRef};
use serde::{Deserialize, Serialize, de::DeserializeOwned};
use crate::{
Error,
observers::{DifferentialObserver, MapObserver, Observer, ObserverWithHashField},
};
#[derive(Serialize, Deserialize, Debug)]
#[expect(clippy::unsafe_derive_deserialize)]
pub struct ValueObserver<'a, T> {
name: Cow<'static, str>,
pub value: OwnedRef<'a, T>,
}
impl<'a, T> ValueObserver<'a, T> {
#[must_use]
pub fn new(name: &'static str, value: OwnedRef<'a, T>) -> Self {
Self {
name: Cow::from(name),
value,
}
}
#[must_use]
pub fn get_ref(&self) -> &T {
self.value.as_ref()
}
pub fn set(&mut self, new_value: T) {
self.value = OwnedRef::Owned(Box::new(new_value));
}
#[must_use]
pub fn take(self) -> T
where
T: Clone,
{
match self.value {
OwnedRef::RefRaw(r, _) => unsafe { (*r).clone() },
OwnedRef::Ref(r) => r.clone(),
OwnedRef::Owned(v) => *v,
}
}
}
impl<I, S, T> Observer<I, S> for ValueObserver<'_, T> {}
impl<T> Named for ValueObserver<'_, T> {
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<T: Hash> ObserverWithHashField for ValueObserver<'_, T> {
fn hash(&self) -> Option<u64> {
Some(RandomState::with_seeds(1, 2, 3, 4).hash_one(self.value.as_ref()))
}
}
impl<OTA, OTB, I, S, T> DifferentialObserver<OTA, OTB, I, S> for ValueObserver<'_, T> {}
#[derive(Serialize, Deserialize, Debug)]
#[expect(clippy::unsafe_derive_deserialize)]
pub struct RefCellValueObserver<'a, T> {
name: Cow<'static, str>,
pub value: OwnedRef<'a, RefCell<T>>,
}
impl<'a, T> RefCellValueObserver<'a, T> {
#[must_use]
pub fn new(name: &'static str, value: OwnedRef<'a, RefCell<T>>) -> Self {
Self {
name: Cow::from(name),
value,
}
}
#[must_use]
pub fn get_ref<'b>(&'b self) -> Ref<'a, T>
where
'b: 'a,
{
self.value.as_ref().borrow()
}
#[must_use]
pub fn get_ref_mut<'b>(&'b self) -> RefMut<'a, T>
where
'b: 'a,
{
self.value.as_ref().borrow_mut()
}
pub fn set(&mut self, new_value: T) {
self.value.as_ref().replace(new_value);
}
#[must_use]
pub fn take(self) -> T
where
T: Clone,
{
match self.value {
OwnedRef::RefRaw(r, _) => unsafe { (*r).borrow().deref().clone() },
OwnedRef::Ref(r) => r.borrow().deref().clone(),
OwnedRef::Owned(v) => v.borrow().clone(),
}
}
}
impl<I, S, T> Observer<I, S> for RefCellValueObserver<'_, T> {}
impl<T> Named for RefCellValueObserver<'_, T> {
fn name(&self) -> &Cow<'static, str> {
&self.name
}
}
impl<T> ObserverWithHashField for RefCellValueObserver<'_, T>
where
T: Hash,
{
fn hash(&self) -> Option<u64> {
Some(RandomState::with_seeds(1, 2, 3, 4).hash_one(&*self.value.as_ref().borrow()))
}
}
impl<OTA, OTB, I, S, T> DifferentialObserver<OTA, OTB, I, S> for RefCellValueObserver<'_, T> {}
#[derive(Debug)]
pub struct RefCellValueObserverIter<'it, T> {
v: Ref<'it, [T]>,
}
impl<'it, T: 'it, A: Deref<Target = [T]>> AsSlice<'it> for RefCellValueObserver<'_, A> {
type Entry = T;
type SliceRef = Ref<'it, [T]>;
fn as_slice(&'it self) -> Self::SliceRef {
Ref::map(self.value.as_ref().borrow(), |s| &**s)
}
}
impl<'it, T: 'it, A: DerefMut<Target = [T]>> AsSliceMut<'it> for RefCellValueObserver<'_, A> {
type SliceRefMut = RefMut<'it, [T]>;
fn as_slice_mut(&'it mut self) -> Self::SliceRefMut {
RefMut::map(self.value.as_ref().borrow_mut(), |s| &mut **s)
}
}
impl<'it, T: 'it, A: Deref<Target = [T]>> AsIter<'it> for RefCellValueObserver<'_, A> {
type Item = T;
type Ref = Ref<'it, Self::Item>;
type IntoIter = RefCellValueObserverIter<'it, T>;
fn as_iter(&'it self) -> Self::IntoIter {
Self::IntoIter {
v: Ref::map(self.value.as_ref().borrow(), Deref::deref),
}
}
}
impl<'it, T: 'it> Iterator for RefCellValueObserverIter<'it, T> {
type Item = Ref<'it, T>;
fn next(&mut self) -> Option<Self::Item> {
if self.v.is_empty() {
return None;
}
let cloned = Ref::clone(&self.v);
let (next, remainder) = Ref::map_split(cloned, |v| (&v[0], &v[1..]));
self.v = remainder;
Some(next)
}
}
#[derive(Debug)]
pub struct RefCellValueObserverIterMut<'it, T> {
v: Option<RefMut<'it, [T]>>,
}
impl<'it, T: 'it, A: DerefMut<Target = [T]> + Serialize> AsIterMut<'it>
for RefCellValueObserver<'_, A>
{
type RefMut = RefMut<'it, T>;
type IntoIterMut = RefCellValueObserverIterMut<'it, T>;
fn as_iter_mut(&'it mut self) -> Self::IntoIterMut {
Self::IntoIterMut {
v: Some(RefMut::map(
self.value.as_ref().borrow_mut(),
DerefMut::deref_mut,
)),
}
}
}
impl<'it, T: 'it> Iterator for RefCellValueObserverIterMut<'it, T> {
type Item = RefMut<'it, T>;
fn next(&mut self) -> Option<Self::Item> {
match self.v.take() {
Some(v) => {
let next_slice = if v.len() > 1 {
let (next, remainder) = RefMut::map_split(v, |v| v.split_at_mut(1));
self.v = Some(remainder);
next
} else {
v
};
Some(RefMut::map(next_slice, |v| &mut v[0]))
}
_ => None,
}
}
}
impl<A: Hash> Hash for RefCellValueObserver<'_, A> {
#[inline]
fn hash<H: Hasher>(&self, hasher: &mut H) {
self.get_ref().hash(hasher);
}
}
impl<A> HasLen for RefCellValueObserver<'_, A>
where
A: HasLen,
{
fn len(&self) -> usize {
self.get_ref().len()
}
fn is_empty(&self) -> bool {
self.get_ref().is_empty()
}
}
impl<T> AsRef<Self> for RefCellValueObserver<'_, T> {
fn as_ref(&self) -> &Self {
self
}
}
impl<T> AsMut<Self> for RefCellValueObserver<'_, T> {
fn as_mut(&mut self) -> &mut Self {
self
}
}
impl<T, A> MapObserver for RefCellValueObserver<'_, A>
where
T: PartialEq + Copy + Hash + Default + DeserializeOwned + Serialize + Debug,
A: DerefMut<Target = [T]> + Hash + Serialize + DeserializeOwned + HasLen + Default,
{
type Entry = T;
fn get(&self, idx: usize) -> Self::Entry {
self.get_ref()[idx]
}
fn set(&mut self, idx: usize, val: Self::Entry) {
self.get_ref_mut()[idx] = val;
}
fn usable_count(&self) -> usize {
self.get_ref().len()
}
fn count_bytes(&self) -> u64 {
let default = Self::Entry::default();
let mut count = 0;
for entry in self.get_ref().iter() {
if entry != &default {
count += 1;
}
}
count
}
fn reset_map(&mut self) -> Result<(), Error> {
*self.get_ref_mut() = A::default();
Ok(())
}
fn to_vec(&self) -> Vec<Self::Entry> {
self.get_ref().to_vec()
}
fn how_many_set(&self, indexes: &[usize]) -> usize {
let default = Self::Entry::default();
let mut count = 0;
let arr = self.get_ref();
for idx in indexes {
if arr[*idx] != default {
count += 1;
}
}
count
}
fn initial(&self) -> Self::Entry {
Self::Entry::default()
}
}