Skip to content

Commit

Permalink
Merge branch 'fuzz-gix-config'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Dec 24, 2023
2 parents 7661098 + d83b4e0 commit 0f71709
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 15 deletions.
1 change: 1 addition & 0 deletions gix-config/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ cargo-fuzz = true
libfuzzer-sys = "0.4.7"
arbitrary = { version = "1", features = ["derive"] }
bstr = "1.8.0"
anyhow = "1.0.76"

[dependencies.gix-config]
path = ".."
Expand Down
72 changes: 60 additions & 12 deletions gix-config/fuzz/fuzz_targets/fuzz_file.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,75 @@
#![no_main]

use anyhow::Result;
use arbitrary::Arbitrary;
use bstr::BStr;
use gix_config::{
file::{init::Options, Metadata},
File,
};
use libfuzzer_sys::fuzz_target;
use std::error::Error;
use std::fmt;
use std::hint::black_box;

#[derive(Arbitrary, Debug)]
struct Ctx<'a> {
input: &'a [u8],
sections_by_name: &'a str,
section_subsection_key_triples: Vec<(&'a str, Option<&'a [u8]>, &'a str)>,
}

macro_rules! unwrap_or_return {
($e:expr) => {
match $e {
Ok(val) => val,
Err(_) => return,
}
};
}
const DEFAULT_TRIPLE: (&str, Option<&'static [u8]>, &str) = ("section", Some(b"subsection"), "key");

fuzz_target!(|ctx: Ctx| {
fn fuzz(ctx: Ctx) -> Result<()> {
let meta = Metadata::default();
let options = Options::default();
let file = unwrap_or_return!(File::from_bytes_no_includes(&ctx.input, meta.clone(), options.clone()));
let file = File::from_bytes_no_includes(&ctx.input, meta.clone(), options.clone())?;

let mut triples = ctx.section_subsection_key_triples.iter();

let (section_name, subsection_name, key) = triples.next().unwrap_or(&DEFAULT_TRIPLE);
_ = black_box(file.string(section_name, subsection_name.map(|x| BStr::new(x)), key));
_ = black_box(file.string_by_key(BStr::new(key)));
_ = black_box(file.string_filter(section_name, subsection_name.map(|x| BStr::new(x)), key, &mut |_| false));
_ = black_box(file.string_filter_by_key(BStr::new(key), &mut |_| false));

let (section_name, subsection_name, key) = triples.next().unwrap_or(&DEFAULT_TRIPLE);
_ = black_box(file.path(section_name, subsection_name.map(|x| BStr::new(x)), key));
_ = black_box(file.path_by_key(BStr::new(key)));
_ = black_box(file.path_filter(section_name, subsection_name.map(|x| BStr::new(x)), key, &mut |_| false));
_ = black_box(file.path_filter_by_key(BStr::new(key), &mut |_| false));

let (section_name, subsection_name, key) = triples.next().unwrap_or(&DEFAULT_TRIPLE);
_ = black_box(file.boolean(section_name, subsection_name.map(|x| BStr::new(x)), key));
_ = black_box(file.boolean_by_key(BStr::new(key)));
_ = black_box(file.boolean_filter(section_name, subsection_name.map(|x| BStr::new(x)), key, &mut |_| false));
_ = black_box(file.boolean_filter_by_key(BStr::new(key), &mut |_| false));

let (section_name, subsection_name, key) = triples.next().unwrap_or(&DEFAULT_TRIPLE);
_ = black_box(file.integer(section_name, subsection_name.map(|x| BStr::new(x)), key));
_ = black_box(file.integer_by_key(BStr::new(key)));
_ = black_box(file.integer_filter(section_name, subsection_name.map(|x| BStr::new(x)), key, &mut |_| false));
_ = black_box(file.integer_filter_by_key(BStr::new(key), &mut |_| false));

let (section_name, subsection_name, key) = triples.next().unwrap_or(&DEFAULT_TRIPLE);
_ = black_box(file.strings(section_name, subsection_name.map(|x| BStr::new(x)), key));
_ = black_box(file.strings_by_key(BStr::new(key)));
_ = black_box(file.strings_filter(section_name, subsection_name.map(|x| BStr::new(x)), key, &mut |_| false));
_ = black_box(file.strings_filter_by_key(BStr::new(key), &mut |_| false));

let (section_name, subsection_name, key) = triples.next().unwrap_or(&DEFAULT_TRIPLE);
_ = black_box(file.integers(section_name, subsection_name.map(|x| BStr::new(x)), key));
_ = black_box(file.integers_by_key(BStr::new(key)));
_ = black_box(file.integers_filter(section_name, subsection_name.map(|x| BStr::new(x)), key, &mut |_| false));
_ = black_box(file.integers_filter_by_key(BStr::new(key), &mut |_| false));

let (section_name, subsection_name, key) = triples.next().unwrap_or(&DEFAULT_TRIPLE);
_ = black_box(file.integers(section_name, subsection_name.map(|x| BStr::new(x)), key));
_ = black_box(file.integers_by_key(BStr::new(key)));
_ = black_box(file.integers_filter(section_name, subsection_name.map(|x| BStr::new(x)), key, &mut |_| false));
_ = black_box(file.integers_filter_by_key(BStr::new(key), &mut |_| false));

_ = black_box(file.sections().count());
_ = black_box(file.sections_and_ids().count());
_ = black_box(file.sections_and_postmatter().count());
Expand All @@ -44,9 +87,14 @@ fuzz_target!(|ctx: Ctx| {
}

let roundtrip_as_string: Vec<u8> = file.to_bstring().into();
_ = unwrap_or_return!(black_box(File::from_bytes_no_includes(
_ = black_box(File::from_bytes_no_includes(
&roundtrip_as_string,
meta.clone(),
options.clone(),
)));
))?;
Ok(())
}

fuzz_target!(|ctx: Ctx| {
_ = black_box(fuzz(ctx));
});
22 changes: 22 additions & 0 deletions gix-config/fuzz/fuzz_targets/fuzz_file_corpus_builder.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash

set -eox pipefail

CWD=$(pwd)

ROOT=$1
OUTPUT_CORPUS=$2
FIXTURES_DIR=$(readlink -f $ROOT/gix-config/tests/fixtures)

echo $ROOT
echo $FIXTURES_DIR
find $FIXTURES_DIR -name "*.config" -exec zip -j $OUTPUT_CORPUS {} \;

# Generate configs.
REPO=$(mktemp -d)
cd $REPO
bash $FIXTURES_DIR/make_config_repo.sh
find . -name ".*" -exec zip $OUTPUT_CORPUS {} \;
cd $CWD
rm -r $REPO

23 changes: 20 additions & 3 deletions gix-ref/fuzz/fuzz_targets/fuzz_log.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
#![no_main]

use anyhow::Result;
use arbitrary::Arbitrary;
use gix_ref::file::log;
use libfuzzer_sys::fuzz_target;
use std::hint::black_box;

fn fuzz(line: &[u8]) -> Result<()> {
let line = log::LineRef::from_bytes(line)?;
#[derive(Arbitrary, Debug)]
struct Ctx<'a> {
line_ref: &'a [u8],
multi_line_reverse: &'a [u8],
multi_line_forward: &'a [u8],
}

fn fuzz(ctx: Ctx) -> Result<()> {
let line = log::LineRef::from_bytes(ctx.line_ref)?;
_ = black_box(line.previous_oid());
_ = black_box(line.new_oid());

let mut buf = [0u8; 1024];
let read = std::io::Cursor::new(ctx.multi_line_reverse);
let mut iter = gix_ref::file::log::iter::reverse(read, &mut buf)?;
_ = black_box(iter.map(|x| black_box(x)).count());

let mut iter = gix_ref::file::log::iter::forward(ctx.multi_line_forward);
_ = black_box(iter.map(|x| black_box(x)).count());

Ok(())
}

fuzz_target!(|ctx: &[u8]| {
fuzz_target!(|ctx: Ctx| {
_ = black_box(fuzz(ctx));
});

0 comments on commit 0f71709

Please sign in to comment.