1#![doc = include_str!("../README.md")]
5#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
7#![no_std]
8#![cfg_attr(nightly, feature(specialization))]
10#![cfg_attr(nightly, feature(portable_simd))]
12#![cfg_attr(
13 not(test),
14 warn(
15 missing_debug_implementations,
16 missing_docs,
17 trivial_numeric_casts,
18 unused_extern_crates,
19 unused_import_braces,
20 unused_qualifications,
21 )
22)]
23#![cfg_attr(
24 test,
25 deny(
26 bad_style,
27 dead_code,
28 improper_ctypes,
29 missing_debug_implementations,
30 missing_docs,
31 no_mangle_generic_items,
32 non_shorthand_field_patterns,
33 overflowing_literals,
34 path_statements,
35 patterns_in_fns_without_body,
36 trivial_numeric_casts,
37 unconditional_recursion,
38 unfulfilled_lint_expectations,
39 unused_allocation,
40 unused_comparisons,
41 unused_extern_crates,
42 unused_import_braces,
43 unused_must_use,
44 unused_parens,
45 unused_qualifications,
46 unused,
47 while_true
48 )
49)]
50
51#[cfg(feature = "std")]
52#[macro_use]
53extern crate std;
54#[macro_use]
55#[doc(hidden)]
56pub extern crate alloc;
57
58#[cfg(feature = "derive")]
60#[expect(unused_imports)]
61#[macro_use]
62extern crate libafl_derive;
63#[cfg(feature = "derive")]
64#[doc(hidden)]
65pub use libafl_derive::*;
66
67pub mod common;
68pub use common::*;
69pub mod corpus;
70pub mod events;
71pub mod executors;
72pub mod feedbacks;
73pub mod fuzzer;
74pub mod generators;
75pub mod inputs;
76pub mod monitors;
77pub mod mutators;
78pub mod observers;
79pub mod schedulers;
80pub mod stages;
81pub mod state;
82
83pub use fuzzer::*;
84pub use libafl_bolts::{Error, nonzero};
85
86#[cfg(feature = "prelude")]
88pub mod prelude {
89 #![expect(ambiguous_glob_reexports)]
90
91 pub use super::{
92 corpus::*, events::*, executors::*, feedbacks::*, fuzzer::*, generators::*, inputs::*,
93 monitors::*, mutators::*, observers::*, schedulers::*, stages::*, state::*, *,
94 };
95}
96
97#[cfg(all(any(doctest, test), not(feature = "std")))]
98#[unsafe(no_mangle)]
100pub unsafe extern "C" fn external_current_millis() -> u64 {
101 1000
103}
104
105#[cfg(feature = "std")]
106#[cfg(test)]
107mod tests {
108
109 #[cfg(miri)]
110 use libafl_bolts::serdeany::RegistryBuilder;
111 use libafl_bolts::{
112 rands::{RomuDuoJrRand, StdRand},
113 tuples::tuple_list,
114 };
115
116 #[cfg(miri)]
117 use crate::stages::ExecutionCountRestartHelperMetadata;
118 use crate::{
119 StdFuzzer,
120 corpus::{Corpus, InMemoryCorpus, Testcase},
121 events::NopEventManager,
122 executors::{ExitKind, InProcessExecutor},
123 feedbacks::ConstFeedback,
124 fuzzer::Fuzzer,
125 inputs::BytesInput,
126 monitors::SimpleMonitor,
127 mutators::{StdScheduledMutator, mutations::BitFlipMutator},
128 schedulers::RandScheduler,
129 stages::StdMutationalStage,
130 state::{HasCorpus, StdState},
131 };
132
133 #[test]
134 fn test_fuzzer() {
135 #[cfg(miri)]
138 unsafe {
139 RegistryBuilder::register::<ExecutionCountRestartHelperMetadata>();
140 }
141
142 let rand = StdRand::with_seed(0);
143
144 let mut corpus = InMemoryCorpus::<BytesInput>::new();
145 let testcase = Testcase::new(vec![0; 4].into());
146 corpus.add(testcase).unwrap();
147
148 let mut feedback = ConstFeedback::new(false);
149 let mut objective = ConstFeedback::new(false);
150
151 let mut state = StdState::new(
152 rand,
153 corpus,
154 InMemoryCorpus::<BytesInput>::new(),
155 &mut feedback,
156 &mut objective,
157 )
158 .unwrap();
159
160 let _monitor = SimpleMonitor::new(|s| {
161 println!("{s}");
162 });
163 let mut event_manager = NopEventManager::new();
164
165 let feedback = ConstFeedback::new(false);
166 let objective = ConstFeedback::new(false);
167
168 let scheduler = RandScheduler::new();
169 let mut fuzzer = StdFuzzer::new(scheduler, feedback, objective);
170
171 let mut harness = |_buf: &BytesInput| ExitKind::Ok;
172 let mut executor = InProcessExecutor::new(
173 &mut harness,
174 tuple_list!(),
175 &mut fuzzer,
176 &mut state,
177 &mut event_manager,
178 )
179 .unwrap();
180
181 let mutator = StdScheduledMutator::new(tuple_list!(BitFlipMutator::new()));
182 let mut stages = tuple_list!(StdMutationalStage::new(mutator));
183
184 for i in 0..1000 {
185 fuzzer
186 .fuzz_one(&mut stages, &mut executor, &mut state, &mut event_manager)
187 .unwrap_or_else(|_| panic!("Error in iter {i}"));
188 if cfg!(miri) {
189 break;
190 }
191 }
192
193 let state_serialized = postcard::to_allocvec(&state).unwrap();
194 let state_deserialized: StdState<
195 InMemoryCorpus<BytesInput>,
196 _,
197 StdRand,
198 InMemoryCorpus<BytesInput>,
199 > = postcard::from_bytes::<
200 StdState<
201 InMemoryCorpus<BytesInput>,
202 BytesInput,
203 RomuDuoJrRand,
204 InMemoryCorpus<BytesInput>,
205 >,
206 >(state_serialized.as_slice())
207 .unwrap();
208 assert_eq!(state.corpus().count(), state_deserialized.corpus().count());
209
210 let corpus_serialized = postcard::to_allocvec(state.corpus()).unwrap();
211 let corpus_deserialized: InMemoryCorpus<BytesInput> =
212 postcard::from_bytes(corpus_serialized.as_slice()).unwrap();
213 assert_eq!(state.corpus().count(), corpus_deserialized.count());
214 }
215}