Skip to content

Commit 7e2add3

Browse files
committed
Merge branch 'fuzz-gix-commitgraph'
2 parents 5e84453 + 672294e commit 7e2add3

File tree

4 files changed

+91
-18
lines changed

4 files changed

+91
-18
lines changed

gix-commitgraph/fuzz/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
target
2+
corpus
3+
artifacts
4+
coverage

gix-commitgraph/fuzz/Cargo.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[package]
2+
name = "gix-commitgraph-fuzz"
3+
version = "0.0.0"
4+
publish = false
5+
edition = "2021"
6+
7+
[package.metadata]
8+
cargo-fuzz = true
9+
10+
[dependencies]
11+
anyhow = "1.0.76"
12+
arbitrary = { version = "1.3.2", features = ["derive"] }
13+
libfuzzer-sys = "0.4"
14+
memmap2 = "0.9.0"
15+
16+
[dependencies.gix-commitgraph]
17+
path = ".."
18+
19+
# Prevent this from interfering with workspaces
20+
[workspace]
21+
members = ["."]
22+
23+
[profile.release]
24+
debug = 1
25+
26+
[[bin]]
27+
name = "fuzz_file"
28+
path = "fuzz_targets/fuzz_file.rs"
29+
test = false
30+
doc = false
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#![no_main]
2+
3+
use anyhow::Result;
4+
use gix_commitgraph::File;
5+
use libfuzzer_sys::fuzz_target;
6+
use std::hint::black_box;
7+
8+
fn fuzz(data: &[u8]) -> Result<()> {
9+
let data = {
10+
let mut d = memmap2::MmapMut::map_anon(data.len())?;
11+
d.copy_from_slice(data);
12+
d.make_read_only()?
13+
};
14+
let file = File::new(data, "does not matter".into())?;
15+
16+
_ = black_box(file.iter_base_graph_ids().count());
17+
_ = black_box(file.iter_commits().count());
18+
_ = black_box(file.iter_ids().count());
19+
20+
let _ = black_box(file.checksum());
21+
let _ = black_box(file.verify_checksum());
22+
let _ = black_box(file.object_hash());
23+
24+
Ok(())
25+
}
26+
27+
fuzz_target!(|data: &[u8]| {
28+
_ = black_box(fuzz(data));
29+
});

gix-commitgraph/src/file/init.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::path::PathBuf;
12
use std::{
23
convert::{TryFrom, TryInto},
34
path::Path,
@@ -62,24 +63,13 @@ impl File {
6263
pub fn at(path: impl AsRef<Path>) -> Result<File, Error> {
6364
Self::try_from(path.as_ref())
6465
}
65-
}
6666

67-
impl TryFrom<&Path> for File {
68-
type Error = Error;
69-
70-
fn try_from(path: &Path) -> Result<Self, Self::Error> {
71-
let data = std::fs::File::open(path)
72-
.and_then(|file| {
73-
// SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file.
74-
#[allow(unsafe_code)]
75-
unsafe {
76-
Mmap::map(&file)
77-
}
78-
})
79-
.map_err(|e| Error::Io {
80-
err: e,
81-
path: path.to_owned(),
82-
})?;
67+
/// A lower-level constructor which constructs a new instance directly from the mapping in `data`,
68+
/// assuming that it originated from `path`.
69+
///
70+
/// Note that `path` is only used for verification of the hash its basename contains, but otherwise
71+
/// is not of importance.
72+
pub fn new(data: memmap2::Mmap, path: PathBuf) -> Result<File, Error> {
8373
let data_size = data.len();
8474
if data_size < MIN_FILE_SIZE {
8575
return Err(Error::Corrupt(
@@ -240,13 +230,33 @@ impl TryFrom<&Path> for File {
240230
extra_edges_list_range,
241231
fan,
242232
oid_lookup_offset,
243-
path: path.to_owned(),
233+
path,
244234
hash_len: object_hash.len_in_bytes(),
245235
object_hash,
246236
})
247237
}
248238
}
249239

240+
impl TryFrom<&Path> for File {
241+
type Error = Error;
242+
243+
fn try_from(path: &Path) -> Result<Self, Self::Error> {
244+
let data = std::fs::File::open(path)
245+
.and_then(|file| {
246+
// SAFETY: we have to take the risk of somebody changing the file underneath. Git never writes into the same file.
247+
#[allow(unsafe_code)]
248+
unsafe {
249+
Mmap::map(&file)
250+
}
251+
})
252+
.map_err(|e| Error::Io {
253+
err: e,
254+
path: path.to_owned(),
255+
})?;
256+
Self::new(data, path.to_owned())
257+
}
258+
}
259+
250260
// Copied from gix-odb/pack/index/init.rs
251261
fn read_fan(d: &[u8]) -> ([u32; FAN_LEN], usize) {
252262
let mut fan = [0; FAN_LEN];

0 commit comments

Comments
 (0)