Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/znippy

plugins/native/znippy-plugin-git/fuzz/src/write_seeds.rs

//! Write the fuzz corpus seeds for `read_paths`: one valid input per read path
//! (prefixed with its selector byte) and every hostile fixture under each path.
use std::path::PathBuf;
use std::sync::Arc;

use znippy_common::arrow::array::{BinaryBuilder, RecordBatch, StringBuilder, UInt64Builder};
use znippy_common::arrow::datatypes::{DataType, Field, Schema};
use znippy_common::arrow::ipc::writer::StreamWriter;
use znippy_plugin_git::exploded_arrow::{ExplodePolicy, ExplodedArchive};
use znippy_plugin_git::index_layout::{ObjectIndex, OneTableFourColumns, synthetic_entries};
use znippy_plugin_git::{CommitNode, GitObjectKind, reach_schema};

fn stream(batch: &RecordBatch) -> Vec<u8> {
    let mut out = Vec::new();
    let mut w = StreamWriter::try_new(&mut out, &batch.schema()).unwrap();
    w.write(batch).unwrap();
    w.finish().unwrap();
    out
}

fn main() {
    let dir = PathBuf::from(std::env::args().nth(1).expect("corpus dir"));
    std::fs::create_dir_all(&dir).unwrap();
    let mut seeds: Vec<(u8, Vec<u8>)> = Vec::new();

    let nodes = vec![
        CommitNode {
            oid: "a".repeat(40),
            parents: vec![],
            tree: Some("t".repeat(40)),
            committer_time: Some(1),
            generation: 1,
        },
        CommitNode {
            oid: "b".repeat(40),
            parents: vec!["a".repeat(40)],
            tree: None,
            committer_time: None,
            generation: 2,
        },
    ];
    seeds.push((0, znippy_plugin_git::graph::encode_graph(&nodes).unwrap()));

    let mut o = StringBuilder::new();
    let mut c = UInt64Builder::new();
    let mut b = BinaryBuilder::new();
    o.append_value("a".repeat(40));
    c.append_value(0);
    b.append_value([58u8, 48, 0, 0, 0, 0, 0, 0]);
    let batch = RecordBatch::try_new(
        reach_schema(),
        vec![
            Arc::new(o.finish()),
            Arc::new(c.finish()),
            Arc::new(b.finish()),
        ],
    )
    .unwrap();
    seeds.push((1, stream(&batch)));

    let schema = Arc::new(Schema::new(vec![Field::new("name", DataType::Utf8, false)]));
    let mut log = Vec::new();
    for n in ["refs/heads/main", "refs/heads/x"] {
        let mut s = StringBuilder::new();
        s.append_value(n);
        log.extend(stream(
            &RecordBatch::try_new(schema.clone(), vec![Arc::new(s.finish())]).unwrap(),
        ));
    }
    seeds.push((2, log));

    let mut j = znippy_plugin_git::archive_write::encode_journal_schema().unwrap();
    j.extend(znippy_plugin_git::archive_write::encode_journal_row(0, 100).unwrap());
    j.extend(znippy_plugin_git::archive_write::encode_journal_row(100, 7).unwrap());
    seeds.push((3, j));

    let p = std::env::temp_dir().join(format!("plugin-git-seed-{}.arrow", std::process::id()));
    let _ = std::fs::remove_file(&p);
    {
        let t = ExplodedArchive::open_with_policy(&p, ExplodePolicy::Full).unwrap();
        t.explode_at(
            &[1; 20],
            GitObjectKind::Commit,
            Some(0o100644),
            Some("a/b"),
            b"tree x\n",
        )
        .unwrap();
        t.explode(&[2; 20], GitObjectKind::Blob, &[b'z'; 3000])
            .unwrap();
        t.flush().unwrap();
    }
    seeds.push((4, std::fs::read(&p).unwrap()));
    let _ = std::fs::remove_file(&p);

    let ix = OneTableFourColumns::build(&synthetic_entries(3, 20, 7)).unwrap();
    seeds.push((5, ix.persisted_bytes().unwrap().to_vec()));

    let fixtures =
        PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../../../tests/fixtures/hostile-ipc");
    let mut hostile = Vec::new();
    for e in std::fs::read_dir(fixtures).unwrap() {
        hostile.push(std::fs::read(e.unwrap().path()).unwrap());
    }
    let mut n = 0;
    for (sel, bytes) in &seeds {
        let mut v = vec![*sel];
        v.extend(bytes);
        std::fs::write(dir.join(format!("valid-{sel}")), v).unwrap();
        n += 1;
    }
    for (i, h) in hostile.iter().enumerate() {
        for sel in 0..6u8 {
            let mut v = vec![sel];
            v.extend(h);
            std::fs::write(dir.join(format!("hostile-{i}-{sel}")), v).unwrap();
            n += 1;
        }
    }
    println!("{n} seeds in {}", dir.display());
}