mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 12:55:05 +00:00

## Summary I always found it odd that we had to pass this in, since it's really higher-level context for the error. The awkwardness is further evidenced by the fact that we pass in fake values everywhere (even outside of tests). The source path isn't actually used to display the error; it's only accessed elsewhere to _re-display_ the error in certain cases. This PR modifies to instead pass the path directly in those cases.
56 lines
2.2 KiB
Rust
56 lines
2.2 KiB
Rust
//! Fuzzer harness which searches for situations where the parser does not parse or unparse a
|
|
//! particular source snippet consistently.
|
|
|
|
#![no_main]
|
|
|
|
use libfuzzer_sys::{fuzz_target, Corpus};
|
|
use ruff_python_codegen::round_trip;
|
|
use similar::TextDiff;
|
|
|
|
fn do_fuzz(case: &[u8]) -> Corpus {
|
|
let Ok(code) = std::str::from_utf8(case) else {
|
|
return Corpus::Reject;
|
|
};
|
|
|
|
// round trip it once to get a formatted version
|
|
if let Ok(first) = round_trip(code) {
|
|
// round trip it a second time to get a case to compare against
|
|
if let Ok(second) = round_trip(&first) {
|
|
if cfg!(feature = "full-idempotency") {
|
|
// potentially, we don't want to test for full idempotency, but just for unsteady states
|
|
// enable the "full-idempotency" feature when fuzzing for full idempotency
|
|
let diff = TextDiff::from_lines(&first, &second)
|
|
.unified_diff()
|
|
.header("Parsed once", "Parsed twice")
|
|
.to_string();
|
|
assert_eq!(
|
|
first, second,
|
|
"\nIdempotency violation (orig => first => second); original: {:?}\ndiff:\n{}",
|
|
code, diff
|
|
);
|
|
} else if first != second {
|
|
// by the third time we've round-tripped it, we shouldn't be introducing any more
|
|
// changes; if we do, then it's likely that we're in an unsteady parsing state
|
|
let third = round_trip(&second).expect("Couldn't round-trip the processed source.");
|
|
let diff = TextDiff::from_lines(&second, &third)
|
|
.unified_diff()
|
|
.header("Parsed twice", "Parsed three times")
|
|
.to_string();
|
|
assert_eq!(
|
|
second, third,
|
|
"\nPotential unsteady state (orig => first => second => third); original: {:?}\ndiff:\n{}",
|
|
code, diff
|
|
);
|
|
}
|
|
} else {
|
|
panic!(
|
|
"Unable to perform the second round trip!\nbefore: {:?}\nfirst: {:?}",
|
|
code, first
|
|
);
|
|
}
|
|
}
|
|
|
|
Corpus::Keep
|
|
}
|
|
|
|
fuzz_target!(|case: &[u8]| -> Corpus { do_fuzz(case) });
|