summaryrefslogtreecommitdiff
path: root/fuzz
diff options
context:
space:
mode:
authorJohn Turner <jturner.usa@gmail.com>2025-11-16 21:57:40 +0000
committerJohn Turner <jturner.usa@gmail.com>2025-11-16 21:57:40 +0000
commitb360132b9992bf2f242a6ce0927464d6d04ffa02 (patch)
treeb40ac72e6ffbb69bcf7942a8c6369d9bc20fa7fc /fuzz
parent424bd9d0720e3752c6ff252c6eb0a3425109b765 (diff)
downloadgentoo-utils-b360132b9992bf2f242a6ce0927464d6d04ffa02.tar.gz
generate corpus to fuzz on with meson
Diffstat (limited to 'fuzz')
-rw-r--r--fuzz/fuzz.rs2
-rw-r--r--fuzz/gencorpus.rs64
-rw-r--r--fuzz/meson.build19
3 files changed, 83 insertions, 2 deletions
diff --git a/fuzz/fuzz.rs b/fuzz/fuzz.rs
index 69804e8..72f751b 100644
--- a/fuzz/fuzz.rs
+++ b/fuzz/fuzz.rs
@@ -19,7 +19,7 @@ pub unsafe extern "C" fn LLVMFuzzerTestOneInput(input: *const u8, len: usize) ->
let mut proc = Command::new("atom.py")
.stdin(Stdio::piped())
.spawn()
- .unwrap();
+ .expect("failed to start atom.py");
proc.stdin
.as_mut()
diff --git a/fuzz/gencorpus.rs b/fuzz/gencorpus.rs
new file mode 100644
index 0000000..67ba1e3
--- /dev/null
+++ b/fuzz/gencorpus.rs
@@ -0,0 +1,64 @@
+use std::{
+ env,
+ error::Error,
+ fs::{self, OpenOptions},
+ io::Write,
+ path::PathBuf,
+};
+
+use gentoo_utils::{
+ atom::Atom,
+ ebuild::{Depend, repo::Repo},
+};
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let corpus_dir = PathBuf::from(
+ env::args()
+ .nth(1)
+ .expect("expected corpus directory as first argument"),
+ );
+
+ fs::create_dir_all(&corpus_dir)?;
+
+ let repo = Repo::new("/var/db/repos/gentoo");
+ let mut atoms = Vec::new();
+
+ for category in repo.categories()? {
+ for ebuild in category?.ebuilds()? {
+ let depend = ebuild?.depend().to_vec();
+
+ for expr in depend {
+ walk_expr(&mut atoms, &expr);
+ }
+ }
+ }
+
+ for (i, atom) in atoms.iter().enumerate() {
+ let path = corpus_dir.as_path().join(i.to_string());
+ let mut file = OpenOptions::new()
+ .write(true)
+ .truncate(true)
+ .create(true)
+ .open(path)?;
+
+ write!(file, "{atom}")?;
+ }
+
+ Ok(())
+}
+
+fn walk_expr(atoms: &mut Vec<Atom>, depend: &Depend<Atom>) {
+ match depend {
+ Depend::Element(atom) => {
+ atoms.push(atom.clone());
+ }
+ Depend::AllOf(exprs)
+ | Depend::OneOf(exprs)
+ | Depend::AnyOf(exprs)
+ | Depend::ConditionalGroup(_, exprs) => {
+ for expr in exprs {
+ walk_expr(atoms, expr);
+ }
+ }
+ }
+}
diff --git a/fuzz/meson.build b/fuzz/meson.build
index c4b5e8d..d6809f6 100644
--- a/fuzz/meson.build
+++ b/fuzz/meson.build
@@ -1,5 +1,20 @@
cbindgen = find_program('cbindgen')
+gencorpus = executable(
+ 'gencorpus',
+ 'gencorpus.rs',
+ dependencies: [mon],
+ link_with: [gentoo_utils],
+)
+
+corpus_directory = meson.current_build_dir() / 'corpus'
+
+corpus = custom_target(
+ 'corpus',
+ output: 'corpus',
+ command: [gencorpus, corpus_directory],
+)
+
fuzz_h = custom_target(
'fuzz_h',
input: 'fuzz.rs',
@@ -20,8 +35,10 @@ fuzz_rs = static_library(
link_with: [gentoo_utils],
)
-fuzz_cpp = executable(
+fuzz = executable(
'fuzz',
link_args: ['-fsanitize=fuzzer'],
link_with: [fuzz_rs],
)
+
+test('fuzz', fuzz, args: [corpus_directory], depends: [corpus], timeout: 0)