#![no_main] use imara_diff::{Algorithm, Diff, InternedInput};use libfuzzer_sys::{Corpus, fuzz_target}; use libfuzzer_sys::arbitrary::{self, Arbitrary, Unstructured}; /// Keep libFuzzer from spending its whole timeout budget in Myers on oversized,/// repetitive inputs while preserving room for historical regression fixtures.const MAX_FUZZ_INPUT_BYTES: usize = 150 * 1024; #[derive(arbitrary::Arbitrary, Debug)]struct Input<'a> { before: &'a [u8], before_str: &'a str, after: &'a [u8], after_str: &'a str,} /// Tests all three diff algorithms (Myers, Histogram, MyersMinimal) with:/// - Computing diffs on arbitrary string inputs/// - Postprocessing with no heuristic and line heuristic/// - Unified diff printing/// - Basic queries (count_additions, count_removals, is_added, is_removed)/// - Hunks iterationfn do_fuzz( Input { before, before_str, after, after_str, }: Input<'_>,) { // Create interned input let input = InternedInput::new(before, after); // Test all three diff algorithms for algorithm in [ Algorithm::Histogram, Algorithm::Myers, Algorithm::MyersMinimal, ] { // Compute diff let mut diff = Diff::compute(algorithm, &input); // Test basic queries let _ = diff.count_additions(); let _ = diff.count_removals(); // Test hunks iteration for hunk in diff.hunks() { let _ = hunk.is_pure_insertion(); let _ = hunk.is_pure_removal(); let _ = hunk.invert(); } // Test postprocessing with no heuristic diff.postprocess_no_heuristic(&input); // Test postprocessing with line heuristic diff.postprocess_lines(&input); } let input = InternedInput::new(before_str, after_str); let mut word_input = InternedInput::default(); let mut word_diff = Diff::default(); let diff = Diff::compute(Algorithm::Myers, &input); for hunk in diff.hunks() { hunk.latin_word_diff(&input, &mut word_input, &mut word_diff); }} fuzz_target!(|data: &[u8]| -> Corpus { if data.len() > MAX_FUZZ_INPUT_BYTES { return Corpus::Reject; } let Ok(input) = Input::arbitrary_take_rest(Unstructured::new(data)) else { return Corpus::Reject; }; do_fuzz(input); Corpus::Keep});
#![no_main]
use imara_diff::{Algorithm, Diff, InternedInput};
use libfuzzer_sys::{Corpus, fuzz_target};
use libfuzzer_sys::arbitrary::{self, Arbitrary, Unstructured};
/// Keep libFuzzer from spending its whole timeout budget in Myers on oversized,
/// repetitive inputs while preserving room for historical regression fixtures.
const MAX_FUZZ_INPUT_BYTES: usize = 150 * 1024;
#[derive(arbitrary::Arbitrary, Debug)]
struct Input<'a> {
before: &'a [u8],
before_str: &'a str,
after: &'a [u8],
after_str: &'a str,
}
/// Tests all three diff algorithms (Myers, Histogram, MyersMinimal) with:
/// - Computing diffs on arbitrary string inputs
/// - Postprocessing with no heuristic and line heuristic
/// - Unified diff printing
/// - Basic queries (count_additions, count_removals, is_added, is_removed)
/// - Hunks iteration
fn do_fuzz(
Input {
before,
before_str,
after,
after_str,
}: Input<'_>,
) {
// Create interned input
let input = InternedInput::new(before, after);
// Test all three diff algorithms
for algorithm in [
Algorithm::Histogram,
Algorithm::Myers,
Algorithm::MyersMinimal,
] {
// Compute diff
let mut diff = Diff::compute(algorithm, &input);
// Test basic queries
let _ = diff.count_additions();
let _ = diff.count_removals();
// Test hunks iteration
for hunk in diff.hunks() {
let _ = hunk.is_pure_insertion();
let _ = hunk.is_pure_removal();
let _ = hunk.invert();
}
// Test postprocessing with no heuristic
diff.postprocess_no_heuristic(&input);
// Test postprocessing with line heuristic
diff.postprocess_lines(&input);
}
let input = InternedInput::new(before_str, after_str);
let mut word_input = InternedInput::default();
let mut word_diff = Diff::default();
let diff = Diff::compute(Algorithm::Myers, &input);
for hunk in diff.hunks() {
hunk.latin_word_diff(&input, &mut word_input, &mut word_diff);
}
}
fuzz_target!(|data: &[u8]| -> Corpus {
if data.len() > MAX_FUZZ_INPUT_BYTES {
return Corpus::Reject;
}
let Ok(input) = Input::arbitrary_take_rest(Unstructured::new(data)) else {
return Corpus::Reject;
};
do_fuzz(input);
Corpus::Keep
});