mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-03 15:14:42 +00:00
Rename Red Knot (#17820)
This commit is contained in:
parent
e6a798b962
commit
b51c4f82ea
1564 changed files with 1598 additions and 1578 deletions
164
fuzz/fuzz_targets/ty_check_invalid_syntax.rs
Normal file
164
fuzz/fuzz_targets/ty_check_invalid_syntax.rs
Normal file
|
@ -0,0 +1,164 @@
|
|||
//! Fuzzer harness that runs the type checker to catch for panics for source code containing
|
||||
//! syntax errors.
|
||||
|
||||
#![no_main]
|
||||
|
||||
use std::sync::{Arc, Mutex, OnceLock};
|
||||
|
||||
use libfuzzer_sys::{fuzz_target, Corpus};
|
||||
|
||||
use ruff_db::files::{system_path_to_file, File, Files};
|
||||
use ruff_db::system::{
|
||||
DbWithTestSystem, DbWithWritableSystem as _, System, SystemPathBuf, TestSystem,
|
||||
};
|
||||
use ruff_db::vendored::VendoredFileSystem;
|
||||
use ruff_db::{Db as SourceDb, Upcast};
|
||||
use ruff_python_ast::PythonVersion;
|
||||
use ruff_python_parser::{parse_unchecked, Mode, ParseOptions};
|
||||
use ty_python_semantic::lint::LintRegistry;
|
||||
use ty_python_semantic::types::check_types;
|
||||
use ty_python_semantic::{
|
||||
default_lint_registry, lint::RuleSelection, Db as SemanticDb, Program, ProgramSettings,
|
||||
PythonPlatform, SearchPathSettings,
|
||||
};
|
||||
|
||||
/// Database that can be used for testing.
|
||||
///
|
||||
/// Uses an in memory filesystem and it stubs out the vendored files by default.
|
||||
#[salsa::db]
|
||||
#[derive(Clone)]
|
||||
struct TestDb {
|
||||
storage: salsa::Storage<Self>,
|
||||
files: Files,
|
||||
system: TestSystem,
|
||||
vendored: VendoredFileSystem,
|
||||
events: Arc<Mutex<Vec<salsa::Event>>>,
|
||||
rule_selection: Arc<RuleSelection>,
|
||||
}
|
||||
|
||||
impl TestDb {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
storage: salsa::Storage::default(),
|
||||
system: TestSystem::default(),
|
||||
vendored: ty_vendored::file_system().clone(),
|
||||
events: Arc::default(),
|
||||
files: Files::default(),
|
||||
rule_selection: RuleSelection::from_registry(default_lint_registry()).into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl SourceDb for TestDb {
|
||||
fn vendored(&self) -> &VendoredFileSystem {
|
||||
&self.vendored
|
||||
}
|
||||
|
||||
fn system(&self) -> &dyn System {
|
||||
&self.system
|
||||
}
|
||||
|
||||
fn files(&self) -> &Files {
|
||||
&self.files
|
||||
}
|
||||
|
||||
fn python_version(&self) -> PythonVersion {
|
||||
Program::get(self).python_version(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl DbWithTestSystem for TestDb {
|
||||
fn test_system(&self) -> &TestSystem {
|
||||
&self.system
|
||||
}
|
||||
|
||||
fn test_system_mut(&mut self) -> &mut TestSystem {
|
||||
&mut self.system
|
||||
}
|
||||
}
|
||||
|
||||
impl Upcast<dyn SourceDb> for TestDb {
|
||||
fn upcast(&self) -> &(dyn SourceDb + 'static) {
|
||||
self
|
||||
}
|
||||
fn upcast_mut(&mut self) -> &mut (dyn SourceDb + 'static) {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl SemanticDb for TestDb {
|
||||
fn is_file_open(&self, file: File) -> bool {
|
||||
!file.path(self).is_vendored_path()
|
||||
}
|
||||
|
||||
fn rule_selection(&self) -> Arc<RuleSelection> {
|
||||
self.rule_selection.clone()
|
||||
}
|
||||
|
||||
fn lint_registry(&self) -> &LintRegistry {
|
||||
default_lint_registry()
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::db]
|
||||
impl salsa::Database for TestDb {
|
||||
fn salsa_event(&self, event: &dyn Fn() -> salsa::Event) {
|
||||
let event = event();
|
||||
tracing::trace!("event: {:?}", event);
|
||||
let mut events = self.events.lock().unwrap();
|
||||
events.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_db() -> TestDb {
|
||||
let db = TestDb::new();
|
||||
|
||||
let src_root = SystemPathBuf::from("/src");
|
||||
db.memory_file_system()
|
||||
.create_directory_all(&src_root)
|
||||
.unwrap();
|
||||
|
||||
Program::from_settings(
|
||||
&db,
|
||||
ProgramSettings {
|
||||
python_version: PythonVersion::default(),
|
||||
python_platform: PythonPlatform::default(),
|
||||
search_paths: SearchPathSettings::new(vec![src_root]),
|
||||
},
|
||||
)
|
||||
.expect("Valid search path settings");
|
||||
|
||||
db
|
||||
}
|
||||
|
||||
static TEST_DB: OnceLock<Mutex<TestDb>> = OnceLock::new();
|
||||
|
||||
fn do_fuzz(case: &[u8]) -> Corpus {
|
||||
let Ok(code) = std::str::from_utf8(case) else {
|
||||
return Corpus::Reject;
|
||||
};
|
||||
|
||||
let parsed = parse_unchecked(code, ParseOptions::from(Mode::Module));
|
||||
if parsed.has_valid_syntax() {
|
||||
return Corpus::Reject;
|
||||
}
|
||||
|
||||
let mut db = TEST_DB
|
||||
.get_or_init(|| Mutex::new(setup_db()))
|
||||
.lock()
|
||||
.unwrap();
|
||||
|
||||
for path in &["/src/a.py", "/src/a.pyi"] {
|
||||
db.write_file(path, code).unwrap();
|
||||
let file = system_path_to_file(&*db, path).unwrap();
|
||||
check_types(&*db, file);
|
||||
db.memory_file_system().remove_file(path).unwrap();
|
||||
file.sync(&mut *db);
|
||||
}
|
||||
|
||||
Corpus::Keep
|
||||
}
|
||||
|
||||
fuzz_target!(|case: &[u8]| -> Corpus { do_fuzz(case) });
|
Loading…
Add table
Add a link
Reference in a new issue