use wikrs::extract::strip;
use wikrs::parser::parse;
#[test]
fn does_not_panic_on_adversarial_input() {
let cases = [
"{{".repeat(100_000), "}}".repeat(100_000), "[[".repeat(100_000), "<ref>".repeat(100_000), "<!--".repeat(100_000), "{|".repeat(100_000), "'".repeat(200_000), "=".repeat(200_000), "<".repeat(200_000), "[[a|".repeat(50_000), "café☕".repeat(50_000), ];
for c in &cases {
let _ = strip(c); }
}
#[test]
fn stays_linear_on_2mb_input() {
let chunk = "{{t|[[L|x]]}}'''b''' <ref>r</ref> == H ==\n* item\n";
let big = chunk.repeat(2_000_000 / chunk.len());
let start = std::time::Instant::now();
let _ = strip(&big);
let elapsed = start.elapsed();
assert!(
elapsed.as_secs() < 10,
"strip too slow on 2 MB: {elapsed:?}"
);
}
#[test]
fn parser_does_not_panic_on_adversarial_input() {
let cases = [
"{{".repeat(100_000), "}}".repeat(100_000), "[[".repeat(100_000), "<ref>".repeat(100_000), "<!--".repeat(100_000), "{|".repeat(100_000), "{{\n\n".repeat(50_000), "{|\n| x\n".repeat(50_000), "'".repeat(200_000), "=".repeat(200_000), "<".repeat(200_000), "[[a|".repeat(50_000), "café☕".repeat(50_000), "| c || d\n".repeat(100_000), "* item\n".repeat(100_000), "[[File:a|[[x]]".repeat(50_000), "[[File:a|[[x]] cap]]".repeat(50_000), ];
let start = std::time::Instant::now();
for c in &cases {
let _ = parse(c); }
assert!(
start.elapsed().as_secs() < 30,
"parser too slow on adversarial input: {:?}",
start.elapsed()
);
}
#[test]
fn parser_survives_deeply_nested_links() {
let deep = format!("{}{}", "[[a|".repeat(50_000), "]]".repeat(50_000));
let _ = parse(&deep);
}
#[test]
fn parser_stays_linear_on_2mb_input() {
let chunk = "{{t|[[L|x]]}}'''b''' <ref>r</ref> == H ==\n* item\n| c || d\n";
let big = chunk.repeat(2_000_000 / chunk.len());
let start = std::time::Instant::now();
let _ = parse(&big);
assert!(start.elapsed().as_secs() < 10, "parse too slow on 2 MB");
}