Rename string stages to unicode stages for consistency (#2293)

This commit is contained in:
Dominik Maier 2024-06-08 16:59:49 +01:00 committed by GitHub
parent e905743ef6
commit 93085782d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 69 additions and 68 deletions

View File

@ -13,10 +13,10 @@ use libafl::{
feedbacks::{CrashFeedback, MaxMapFeedback},
fuzzer::{Fuzzer, StdFuzzer},
inputs::{BytesInput, HasTargetBytes},
mutators::{StdScheduledMutator, StringCategoryRandMutator, StringSubcategoryRandMutator},
mutators::{StdScheduledMutator, UnicodeCategoryRandMutator, UnicodeSubcategoryRandMutator},
observers::StdMapObserver,
schedulers::QueueScheduler,
stages::{mutational::StdMutationalStage, StringIdentificationStage},
stages::{mutational::StdMutationalStage, UnicodeIdentificationStage},
state::StdState,
Evaluator,
};
@ -121,14 +121,14 @@ pub fn main() {
// Setup a mutational stage with a basic bytes mutator
let mutator = StdScheduledMutator::new(tuple_list!(
StringCategoryRandMutator,
StringSubcategoryRandMutator,
StringSubcategoryRandMutator,
StringSubcategoryRandMutator,
StringSubcategoryRandMutator
UnicodeCategoryRandMutator,
UnicodeSubcategoryRandMutator,
UnicodeSubcategoryRandMutator,
UnicodeSubcategoryRandMutator,
UnicodeSubcategoryRandMutator
));
let mut stages = tuple_list!(
StringIdentificationStage::new(),
UnicodeIdentificationStage::new(),
StdMutationalStage::transforming(mutator)
);

View File

@ -85,7 +85,7 @@ concolic_mutation = ["z3"]
## Enable the fancy TuiMonitor for a termanal UI using crossterm
tui_monitor = ["ratatui", "crossterm"]
## Enables `StringClassificationStage` and associated mutators, which allow for mutations which preserve the Unicode property data
## Enables `UnicodeClassificationStage` and associated mutators, which allow for mutations which preserve the Unicode property data
unicode = ["libafl_bolts/alloc", "ahash/std", "serde/rc", "bitvec"]
## Enable multi-part input formats and mutators

View File

@ -21,9 +21,9 @@ pub mod tuneable;
pub use tuneable::*;
#[cfg(feature = "unicode")]
pub mod string;
pub mod unicode;
#[cfg(feature = "unicode")]
pub use string::*;
pub use unicode::*;
#[cfg(feature = "multipart_inputs")]
pub mod multi;

View File

@ -1,4 +1,5 @@
//! Mutators for preserving string categories, which may be useful for certain targets which are primarily string-oriented.
//! Mutators for preserving unicode string categories,
//! which may be useful for certain targets which are primarily string-oriented.
use alloc::{borrow::Cow, vec::Vec};
use core::{
cmp::{Ordering, Reverse},
@ -14,7 +15,7 @@ use crate::{
stages::{
extract_metadata,
mutational::{MutatedTransform, MutatedTransformPost},
StringIdentificationMetadata,
UnicodeIdentificationMetadata,
},
state::{HasCorpus, HasMaxSize, HasRand},
HasMetadata,
@ -27,17 +28,17 @@ use crate::{
pub mod unicode_categories;
/// Input which contains the context necessary to perform unicode mutations
pub type UnicodeInput = (BytesInput, StringIdentificationMetadata);
pub type UnicodeInput = (BytesInput, UnicodeIdentificationMetadata);
impl<S> MutatedTransform<BytesInput, S> for UnicodeInput
where
S: HasCorpus<Input = BytesInput> + HasTestcase,
{
type Post = StringIdentificationMetadata;
type Post = UnicodeIdentificationMetadata;
fn try_transform_from(base: &mut Testcase<BytesInput>, state: &S) -> Result<Self, Error> {
let input = base.load_input(state.corpus())?.clone();
let metadata = base.metadata::<StringIdentificationMetadata>().cloned()?;
let metadata = base.metadata::<UnicodeIdentificationMetadata>().cloned()?;
Ok((input, metadata))
}
@ -46,7 +47,7 @@ where
}
}
impl<S> MutatedTransformPost<S> for StringIdentificationMetadata
impl<S> MutatedTransformPost<S> for UnicodeIdentificationMetadata
where
S: HasTestcase,
{
@ -64,7 +65,7 @@ const MAX_CHARS: usize = 16;
fn choose_start<R: Rand>(
rand: &mut R,
bytes: &[u8],
meta: &StringIdentificationMetadata,
meta: &UnicodeIdentificationMetadata,
) -> Option<(usize, usize)> {
let idx = rand.below(bytes.len());
let mut options = Vec::new();
@ -268,16 +269,16 @@ fn rand_replace_range<S: HasRand + HasMaxSize, F: Fn(&mut S) -> char>(
/// Mutator which randomly replaces a randomly selected range of bytes with bytes that preserve the
/// range's category
#[derive(Debug, Default)]
pub struct StringCategoryRandMutator;
pub struct UnicodeCategoryRandMutator;
impl Named for StringCategoryRandMutator {
impl Named for UnicodeCategoryRandMutator {
fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("string-category-rand");
&NAME
}
}
impl<S> Mutator<UnicodeInput, S> for StringCategoryRandMutator
impl<S> Mutator<UnicodeInput, S> for UnicodeCategoryRandMutator
where
S: HasRand + HasMaxSize,
{
@ -327,16 +328,16 @@ where
/// Mutator which randomly replaces a randomly selected range of bytes with bytes that preserve the
/// range's subcategory
#[derive(Debug, Default)]
pub struct StringSubcategoryRandMutator;
pub struct UnicodeSubcategoryRandMutator;
impl Named for StringSubcategoryRandMutator {
impl Named for UnicodeSubcategoryRandMutator {
fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-rand");
&NAME
}
}
impl<S> Mutator<UnicodeInput, S> for StringSubcategoryRandMutator
impl<S> Mutator<UnicodeInput, S> for UnicodeSubcategoryRandMutator
where
S: HasRand + HasMaxSize,
{
@ -374,16 +375,16 @@ where
/// Mutator which randomly replaces a full category-contiguous region of chars with a random token
#[derive(Debug, Default)]
pub struct StringCategoryTokenReplaceMutator;
pub struct UnicodeCategoryTokenReplaceMutator;
impl Named for StringCategoryTokenReplaceMutator {
impl Named for UnicodeCategoryTokenReplaceMutator {
fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("string-category-token-replace");
&NAME
}
}
impl<S> Mutator<UnicodeInput, S> for StringCategoryTokenReplaceMutator
impl<S> Mutator<UnicodeInput, S> for UnicodeCategoryTokenReplaceMutator
where
S: HasRand + HasMaxSize + HasMetadata,
{
@ -434,16 +435,16 @@ where
/// Mutator which randomly replaces a full subcategory-contiguous region of chars with a random token
#[derive(Debug, Default)]
pub struct StringSubcategoryTokenReplaceMutator;
pub struct UnicodeSubcategoryTokenReplaceMutator;
impl Named for StringSubcategoryTokenReplaceMutator {
impl Named for UnicodeSubcategoryTokenReplaceMutator {
fn name(&self) -> &Cow<'static, str> {
static NAME: Cow<'static, str> = Cow::Borrowed("string-subcategory-replace");
&NAME
}
}
impl<S> Mutator<UnicodeInput, S> for StringSubcategoryTokenReplaceMutator
impl<S> Mutator<UnicodeInput, S> for UnicodeSubcategoryTokenReplaceMutator
where
S: HasRand + HasMaxSize + HasMetadata,
{
@ -499,7 +500,7 @@ mod test {
use crate::{
corpus::NopCorpus,
inputs::{BytesInput, HasMutatorBytes},
mutators::{Mutator, StringCategoryRandMutator, StringSubcategoryRandMutator},
mutators::{Mutator, UnicodeCategoryRandMutator, UnicodeSubcategoryRandMutator},
stages::extract_metadata,
state::StdState,
};
@ -511,7 +512,7 @@ mod test {
let hex = "0123456789abcdef0123456789abcdef";
let mut bytes = BytesInput::from(hex.as_bytes());
let mut mutator = StringCategoryRandMutator;
let mut mutator = UnicodeCategoryRandMutator;
let mut state = StdState::new(
StdRand::with_seed(0),
@ -543,7 +544,7 @@ mod test {
let hex = "0123456789abcdef0123456789abcdef";
let mut bytes = BytesInput::from(hex.as_bytes());
let mut mutator = StringSubcategoryRandMutator;
let mut mutator = UnicodeSubcategoryRandMutator;
let mut state = StdState::new(
StdRand::with_seed(0),

View File

@ -27,8 +27,6 @@ pub use mutational::{MutationalStage, StdMutationalStage};
pub use power::{PowerMutationalStage, StdPowerMutationalStage};
use serde::{Deserialize, Serialize};
pub use stats::AflStatsStage;
#[cfg(feature = "unicode")]
pub use string::*;
#[cfg(feature = "std")]
pub use sync::*;
pub use tmin::{
@ -37,6 +35,8 @@ pub use tmin::{
pub use tracing::{ShadowTracingStage, TracingStage};
pub use tuneable::*;
use tuple_list::NonEmptyTuple;
#[cfg(feature = "unicode")]
pub use unicode::*;
use crate::{
corpus::{CorpusId, HasCurrentCorpusId},
@ -68,12 +68,12 @@ pub mod generation;
pub mod logics;
pub mod power;
pub mod stats;
#[cfg(feature = "unicode")]
pub mod string;
#[cfg(feature = "std")]
pub mod sync;
pub mod tracing;
pub mod tuneable;
#[cfg(feature = "unicode")]
pub mod unicode;
/// A stage is one step in the fuzzing process.
/// Multiple stages will be scheduled one by one for each input.

View File

@ -17,13 +17,13 @@ use crate::{
/// Metadata which stores the list of pre-computed string-like ranges in the input
#[derive(Debug, Default, Serialize, Deserialize, Clone)]
pub struct StringIdentificationMetadata {
pub struct UnicodeIdentificationMetadata {
ranges: Rc<Vec<(usize, BitVec)>>,
}
impl_serdeany!(StringIdentificationMetadata);
impl_serdeany!(UnicodeIdentificationMetadata);
impl StringIdentificationMetadata {
impl UnicodeIdentificationMetadata {
/// The list of pre-computed string-like ranges in the input
#[must_use]
pub fn ranges(&self) -> &Vec<(usize, BitVec)> {
@ -31,7 +31,7 @@ impl StringIdentificationMetadata {
}
}
pub(crate) fn extract_metadata(bytes: &[u8]) -> StringIdentificationMetadata {
pub(crate) fn extract_metadata(bytes: &[u8]) -> UnicodeIdentificationMetadata {
let mut ranges = Vec::new();
if !bytes.is_empty() {
@ -64,24 +64,24 @@ pub(crate) fn extract_metadata(bytes: &[u8]) -> StringIdentificationMetadata {
}
}
StringIdentificationMetadata {
UnicodeIdentificationMetadata {
ranges: Rc::new(ranges),
}
}
/// Stage which identifies potential strings in the provided input
#[derive(Debug)]
pub struct StringIdentificationStage<S> {
pub struct UnicodeIdentificationStage<S> {
phantom: PhantomData<S>,
}
impl<S> Default for StringIdentificationStage<S> {
impl<S> Default for UnicodeIdentificationStage<S> {
fn default() -> Self {
Self::new()
}
}
impl<S> StringIdentificationStage<S> {
impl<S> UnicodeIdentificationStage<S> {
/// Create a new instance of the string identification stage
#[must_use]
pub fn new() -> Self {
@ -91,14 +91,14 @@ impl<S> StringIdentificationStage<S> {
}
}
impl<S> UsesState for StringIdentificationStage<S>
impl<S> UsesState for UnicodeIdentificationStage<S>
where
S: State,
{
type State = S;
}
impl<S, E, EM, Z> Stage<E, EM, Z> for StringIdentificationStage<S>
impl<S, E, EM, Z> Stage<E, EM, Z> for UnicodeIdentificationStage<S>
where
S: HasTestcase<Input = BytesInput> + HasCorpus + State,
E: UsesState<State = S>,
@ -113,7 +113,7 @@ where
_manager: &mut EM,
) -> Result<(), Error> {
let mut tc = state.current_testcase_mut()?;
if tc.has_metadata::<StringIdentificationMetadata>() {
if tc.has_metadata::<UnicodeIdentificationMetadata>() {
return Ok(()); // skip recompute
}

View File

@ -155,8 +155,8 @@ macro_rules! fuzz_with {
mutators::{
GrimoireExtensionMutator, GrimoireRecursiveReplacementMutator, GrimoireRandomDeleteMutator,
GrimoireStringReplacementMutator, havoc_crossover, havoc_mutations, havoc_mutations_no_crossover,
I2SRandReplace, StdScheduledMutator, StringCategoryRandMutator, StringSubcategoryRandMutator,
StringCategoryTokenReplaceMutator, StringSubcategoryTokenReplaceMutator, Tokens, tokens_mutations
I2SRandReplace, StdScheduledMutator, UnicodeCategoryRandMutator, UnicodeSubcategoryRandMutator,
UnicodeCategoryTokenReplaceMutator, UnicodeSubcategoryTokenReplaceMutator, Tokens, tokens_mutations
},
observers::{stacktrace::BacktraceObserver, TimeObserver, CanTrack},
schedulers::{
@ -164,7 +164,7 @@ macro_rules! fuzz_with {
},
stages::{
CalibrationStage, GeneralizationStage, IfStage, StdMutationalStage,
StdPowerMutationalStage, StringIdentificationStage, TracingStage,
StdPowerMutationalStage, UnicodeIdentificationStage, TracingStage,
},
state::{HasCorpus, StdState},
StdFuzzer,
@ -289,29 +289,29 @@ macro_rules! fuzz_with {
// Set up a string category analysis stage for unicode mutations
let unicode_used = $options.unicode();
let string_mutator = StdScheduledMutator::new(
let unicode_mutator = StdScheduledMutator::new(
tuple_list!(
StringCategoryRandMutator,
StringSubcategoryRandMutator,
StringSubcategoryRandMutator,
StringSubcategoryRandMutator,
StringSubcategoryRandMutator,
UnicodeCategoryRandMutator,
UnicodeSubcategoryRandMutator,
UnicodeSubcategoryRandMutator,
UnicodeSubcategoryRandMutator,
UnicodeSubcategoryRandMutator,
)
);
let string_replace_mutator = StdScheduledMutator::new(
let unicode_replace_mutator = StdScheduledMutator::new(
tuple_list!(
StringCategoryTokenReplaceMutator,
StringSubcategoryTokenReplaceMutator,
StringSubcategoryTokenReplaceMutator,
StringSubcategoryTokenReplaceMutator,
StringSubcategoryTokenReplaceMutator,
UnicodeCategoryTokenReplaceMutator,
UnicodeSubcategoryTokenReplaceMutator,
UnicodeSubcategoryTokenReplaceMutator,
UnicodeSubcategoryTokenReplaceMutator,
UnicodeSubcategoryTokenReplaceMutator,
)
);
let string_power = StdMutationalStage::transforming(string_mutator);
let string_replace_power = StdMutationalStage::transforming(string_replace_mutator);
let unicode_power = StdMutationalStage::transforming(unicode_mutator);
let unicode_replace_power = StdMutationalStage::transforming(unicode_replace_mutator);
let string_analysis = StringIdentificationStage::new();
let string_analysis = IfStage::new(|_, _, _, _| Ok((unicode_used && mutator_status.std_mutational).into()), tuple_list!(string_analysis, string_power, string_replace_power));
let unicode_analysis = UnicodeIdentificationStage::new();
let unicode_analysis = IfStage::new(|_, _, _, _| Ok((unicode_used && mutator_status.std_mutational).into()), tuple_list!(unicode_analysis, unicode_power, unicode_replace_power));
// Attempt to use tokens from libfuzzer dicts
if !state.has_metadata::<Tokens>() {
@ -481,7 +481,7 @@ macro_rules! fuzz_with {
calibration,
generalization,
tracing,
string_analysis,
unicode_analysis,
i2s,
cm_i2s,
std_power,