1
0
зеркало из https://github.com/glebtv/tui-textarea.git synced 2026-09-03 14:26:17 +03:00
Files
tui-textarea/fuzz/fuzz_targets/search.rs
srothgan f169a4b18c chore(fuzz): upgrade targets, fix false positives, and add invariant assertions (#11)
- Fix insert_delete target using .unwrap() causing false-positive crashes
  on arbitrary::Error (input exhaustion)
- Fix fuzz Cargo.toml referencing wrong package name (tui-textarea vs
  tui-textarea-2)
- Add invariant assertions (cursor bounds, lines non-empty, selection
  validity) to all targets
- Add 4 new fuzz targets: undo_redo, selection, wrap_render, search
- Expand existing targets with full delete/insert variant coverage,
  input_without_shortcuts, set_yank_text, set_max_histories, and clear
- Add DummyBackend::resize() for variable-width wrap rendering tests
2026-02-19 17:44:58 +10:00

68 строки
1.8 KiB
Rust

#![no_main]
use arbitrary::{Arbitrary, Result, Unstructured};
use libfuzzer_sys::fuzz_target;
use tui_textarea::{CursorMove, TextArea};
use tui_textarea_bench::{dummy_terminal, TerminalExt};
#[derive(Arbitrary)]
enum Op {
SetPattern(String),
SearchForward(bool),
SearchBack(bool),
Move(CursorMove),
InsertStr(String),
DeleteStr(usize),
}
fn assert_invariants(textarea: &TextArea<'_>) {
let lines = textarea.lines();
assert!(!lines.is_empty(), "lines must never be empty");
let (row, col) = textarea.cursor();
assert!(
row < lines.len(),
"cursor row {row} out of bounds (lines: {})",
lines.len()
);
assert!(
col <= lines[row].chars().count(),
"cursor col {col} out of bounds (line {row} chars: {})",
lines[row].chars().count(),
);
}
fn fuzz(data: &[u8]) -> Result<()> {
let mut term = dummy_terminal();
let mut data = Unstructured::new(data);
let text = <&str>::arbitrary(&mut data)?;
let mut textarea = TextArea::from(text.lines());
for _ in 0..100 {
match Op::arbitrary(&mut data)? {
Op::SetPattern(pat) => {
let _ = textarea.set_search_pattern(&pat);
}
Op::SearchForward(match_cursor) => {
textarea.search_forward(match_cursor);
}
Op::SearchBack(match_cursor) => {
textarea.search_back(match_cursor);
}
Op::Move(m) => textarea.move_cursor(m),
Op::InsertStr(s) => {
textarea.insert_str(s);
}
Op::DeleteStr(n) => {
textarea.delete_str(n);
}
}
term.draw_textarea(&textarea);
assert_invariants(&textarea);
}
Ok(())
}
fuzz_target!(|data: &[u8]| {
let _ = fuzz(data);
});