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