tonhowtf/omniget · error

expressão regular inválida

Error message

expressão regular inválida: {}

What it means

`DanmakuFilter::apply` compiles the user-supplied `f.regex` string with the `regex` crate; when the pattern is syntactically invalid the compile error is wrapped in `anyhow!("expressão regular inválida: {}")` and propagated. Empty patterns are skipped (no filtering), so only genuinely malformed regexes trigger this.

Solutions

  1. Validate the regex with `Regex::new(pattern)` before saving the filter and reject invalid input in the UI.
  2. Remove regex constructs unsupported by the Rust regex crate (lookarounds, backreferences) or switch to `fancy-regex` if they are needed.
  3. Trim/sanitize user input; verify no accidental characters outside the intended pattern.
  4. Return a structured error so the frontend can point at the offending pattern field.

Example fix

// before
let f = DanmakuFilter { regex: "(?<=spam)\d+".into(), ..Default::default() };
apply(&elems, &f)?; // panics back with invalid-regex error
// after
if regex::Regex::new(&f.regex).is_err() { return Err(anyhow!("padrão não suportado")); }
apply(&elems, &f)?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_regex(pattern: &str) -> bool {
    regex::Regex::new(pattern.trim()).is_ok()
}

Try / catch

match DanmakuFilter::apply(&elems, &filter) {
    Err(e) if e.to_string().starts_with("expressão regular inválida") => show_regex_error(&filter.regex),
    Err(e) => return Err(e),
    Ok(filtered) => filtered,
}

Prevention

When it happens

Trigger: Calling `apply` with a DanmakuFilter whose `regex` field contains a pattern the regex crate rejects — unbalanced parentheses, invalid escapes like `\d` inside character classes with flags, unescaped `(`, `[a-`, `*+`, or patterns exceeding size/complexity limits (e.g. huge repetition counts like `a{1000000}`).

Common situations: Users typing free-form regex into a danmaku filter UI without validation; porting PCRE/JS regex syntax (lookaheads `(?=...)`, backreferences `\1`) that the Rust regex crate does not support; copy-pasting patterns with smart quotes.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/739ffedfb30bf413. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/src/platforms/bilibili/danmaku/filter.rs:56

/// O `mode` do Bilibili: 1-3 rolam da direita para a esquerda, 4 fica preso no
/// rodapé, 5 no topo. O resto (6 reverso, 7 posicionado, 8 script) é raro e
/// nem chega a ser desenhado no ASS, mas continua valendo no XML e no JSON.
pub fn kind_of(mode: i32) -> &'static str {
    match mode {
        1..=3 => KIND_SCROLL,
        4 => KIND_BOTTOM,
        5 => KIND_TOP,
        _ => KIND_OTHER,
    }
}

pub fn apply(elems: &[DanmakuElem], f: &DanmakuFilter) -> anyhow::Result<Vec<DanmakuElem>> {
    let pattern = f.regex.trim();
    let re = if pattern.is_empty() {
        None
    } else {
        Some(Regex::new(pattern).map_err(|e| anyhow!("expressão regular inválida: {}", e))?)
    };
    let needle = f.keyword.trim().to_lowercase();
    let kinds: Vec<&str> = f
        .kinds
        .iter()
        .map(|s| s.as_str())
        .filter(|s| !s.is_empty())
        .collect();

    let mut kept: Vec<DanmakuElem> = Vec::with_capacity(elems.len());
    for e in elems {
        if !kinds.is_empty() && !kinds.contains(&kind_of(e.mode)) {
            continue;
        }
        let matched = match re.as_ref() {
            Some(r) => r.is_match(&e.content),
            None => {
                if needle.is_empty() {

View on GitHub (pinned to 8600b91f42)