mirror of
https://github.com/uutils/diffutils.git
synced 2026-06-10 15:48:59 -07:00
d73fa831b0
Fixes #223. Very simple reproduction ``` cd diffutils mkdir a touch a/alef a/alefn a/alef_ a/alefx a/alefr a/fuzz.file cargo test ``` => fail https://www.gnu.org/software/diffutils/manual/html_node/Multiple-Patches.html states that the "old" file name has precedence over the "new" filename. I hit this problem because some other (and unfortunately: unknown for now) test issue left bogus `a/alef*` file(s) behind in my workspace. I didn't bother cleaning them up because I assumed some test would keep recreating them and that cost me a lot of time. This issue seems to have existed since the very first commit. Interestingly, there as a previous attempt in 2024 to fix this in commita3a372ff36! So I was apparently not the only affected. BUT that fix was immediately reverted by commitba7cb0aef9in the same PR. Admittedly, that fix seemed somewhat off-topic in https://github.com/uutils/diffutils/pull/33. So here it is again.
75 lines
2.0 KiB
Rust
75 lines
2.0 KiB
Rust
#![no_main]
|
|
#[macro_use]
|
|
extern crate libfuzzer_sys;
|
|
use diffutilslib::params::Params;
|
|
use diffutilslib::unified_diff;
|
|
use std::fs::{self, File};
|
|
use std::io::Write;
|
|
use std::process::Command;
|
|
|
|
fuzz_target!(|x: (Vec<u8>, Vec<u8>, u8)| {
|
|
let (from, to, context) = x;
|
|
/*if let Ok(s) = String::from_utf8(from.clone()) {
|
|
if !s.is_ascii() { return }
|
|
if s.find(|x| x < ' ' && x != '\n').is_some() { return }
|
|
} else {
|
|
return
|
|
}
|
|
if let Ok(s) = String::from_utf8(to.clone()) {
|
|
if !s.is_ascii() { return }
|
|
if s.find(|x| x < ' ' && x != '\n').is_some() { return }
|
|
} else {
|
|
return
|
|
}*/
|
|
fs::create_dir_all("target").unwrap();
|
|
let patched = "target/fuzz.file";
|
|
let diff = unified_diff::diff(
|
|
&from,
|
|
&to,
|
|
&Params {
|
|
from: patched.into(),
|
|
to: patched.into(),
|
|
context_count: context as usize,
|
|
..Default::default()
|
|
},
|
|
);
|
|
File::create("target/fuzz.file.original")
|
|
.unwrap()
|
|
.write_all(&from)
|
|
.unwrap();
|
|
File::create("target/fuzz.file.expected")
|
|
.unwrap()
|
|
.write_all(&to)
|
|
.unwrap();
|
|
File::create("target/fuzz.file")
|
|
.unwrap()
|
|
.write_all(&from)
|
|
.unwrap();
|
|
File::create("target/fuzz.diff")
|
|
.unwrap()
|
|
.write_all(&diff)
|
|
.unwrap();
|
|
let output = Command::new("patch")
|
|
.arg("-p0")
|
|
.arg("--binary")
|
|
.arg("--fuzz=0")
|
|
.stdin(File::open("target/fuzz.diff").unwrap())
|
|
.output()
|
|
.unwrap();
|
|
if !output.status.success() {
|
|
panic!(
|
|
"STDOUT:\n{}\nSTDERR:\n{}",
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
}
|
|
let result = fs::read("target/fuzz.file").unwrap();
|
|
if result != to {
|
|
panic!(
|
|
"STDOUT:\n{}\nSTDERR:\n{}",
|
|
String::from_utf8_lossy(&output.stdout),
|
|
String::from_utf8_lossy(&output.stderr)
|
|
);
|
|
}
|
|
});
|