Skip to content

Commit

Permalink
Merge branch 'fuzz-gix-commitgraph'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Dec 24, 2023
2 parents 5e84453 + 672294e commit 7e2add3
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 18 deletions.
4 changes: 4 additions & 0 deletions gix-commitgraph/fuzz/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target
corpus
artifacts
coverage
30 changes: 30 additions & 0 deletions gix-commitgraph/fuzz/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "gix-commitgraph-fuzz"
version = "0.0.0"
publish = false
edition = "2021"

[package.metadata]
cargo-fuzz = true

[dependencies]
anyhow = "1.0.76"
arbitrary = { version = "1.3.2", features = ["derive"] }
libfuzzer-sys = "0.4"
memmap2 = "0.9.0"

[dependencies.gix-commitgraph]
path = ".."

# Prevent this from interfering with workspaces
[workspace]
members = ["."]

[profile.release]
debug = 1

[[bin]]
name = "fuzz_file"
path = "fuzz_targets/fuzz_file.rs"
test = false
doc = false
29 changes: 29 additions & 0 deletions gix-commitgraph/fuzz/fuzz_targets/fuzz_file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#![no_main]

use anyhow::Result;
use gix_commitgraph::File;
use libfuzzer_sys::fuzz_target;
use std::hint::black_box;

fn fuzz(data: &[u8]) -> Result<()> {
let data = {
let mut d = memmap2::MmapMut::map_anon(data.len())?;
d.copy_from_slice(data);
d.make_read_only()?
};
let file = File::new(data, "does not matter".into())?;

_ = black_box(file.iter_base_graph_ids().count());
_ = black_box(file.iter_commits().count());
_ = black_box(file.iter_ids().count());

let _ = black_box(file.checksum());
let _ = black_box(file.verify_checksum());
let _ = black_box(file.object_hash());

Ok(())
}

fuzz_target!(|data: &[u8]| {
_ = black_box(fuzz(data));
});
46 changes: 28 additions & 18 deletions gix-commitgraph/src/file/init.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::path::PathBuf;
use std::{
convert::{TryFrom, TryInto},
path::Path,
Expand Down Expand Up @@ -62,24 +63,13 @@ impl File {
pub fn at(path: impl AsRef<Path>) -> Result<File, Error> {
Self::try_from(path.as_ref())
}
}

impl TryFrom<&Path> for File {
type Error = Error;

fn try_from(path: &Path) -> Result<Self, Self::Error> {
let data = std::fs::File::open(path)
.and_then(|file| {
// SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file.
#[allow(unsafe_code)]
unsafe {
Mmap::map(&file)
}
})
.map_err(|e| Error::Io {
err: e,
path: path.to_owned(),
})?;
/// A lower-level constructor which constructs a new instance directly from the mapping in `data`,
/// assuming that it originated from `path`.
///
/// Note that `path` is only used for verification of the hash its basename contains, but otherwise
/// is not of importance.
pub fn new(data: memmap2::Mmap, path: PathBuf) -> Result<File, Error> {
let data_size = data.len();
if data_size < MIN_FILE_SIZE {
return Err(Error::Corrupt(
Expand Down Expand Up @@ -240,13 +230,33 @@ impl TryFrom<&Path> for File {
extra_edges_list_range,
fan,
oid_lookup_offset,
path: path.to_owned(),
path,
hash_len: object_hash.len_in_bytes(),
object_hash,
})
}
}

impl TryFrom<&Path> for File {
type Error = Error;

fn try_from(path: &Path) -> Result<Self, Self::Error> {
let data = std::fs::File::open(path)
.and_then(|file| {
// SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file.
#[allow(unsafe_code)]
unsafe {
Mmap::map(&file)
}
})
.map_err(|e| Error::Io {
err: e,
path: path.to_owned(),
})?;
Self::new(data, path.to_owned())
}
}

// Copied from gix-odb/pack/index/init.rs
fn read_fan(d: &[u8]) -> ([u32; FAN_LEN], usize) {
let mut fan = [0; FAN_LEN];
Expand Down

0 comments on commit 7e2add3

Please sign in to comment.