IGNOGlob catastrophic backtracking — ReDoS from an untrusted .gitignoredog/git/IGNO.c's IGNOGlob (IGNO.c:24-66) recurses on EVERY */** suffix
with no memoization and no step budget: for(;;){ if(IGNOGlob(pat,tail)) return
YES; if(empty) break; used1(tail); } (:36-40, :46-51). A single crafted
pattern like *a*a*a*…*a*b matched against a long non-matching path is
exponential-time, and ** nesting compounds it. .gitignore files come from
cloned/untrusted repositories, and every worktree scan (be status, diff, post)
routes through IGNOMatch per chain-file × per pattern (≤256) × per path prefix —
so a hostile repo shipping a crafted .gitignore hangs the process. Method:
Issues.
IGNO.c:24-66 recursive matcher; pattern length bounded only by the mmap'd
file, so ~40 wildcards effectively hangs..gitignore from a clone; IGNOMatch fans it across chain
files, ≤256 patterns, and path prefixes.git
wildmatch technique) OR a hard recursion/step budget that fails closed.dog/git libdog, ABC style; behaviour-preserving on the existing IGNO tests.*a*…*b against a long non-match; assert
it completes under a step budget (dog/fuzz has no IGNO target today).79612854 — unbudgeted recursion still at IGNO.c:24-51. NOTHING landed; a budgeted igno_glob (IGNO_GLOB_BUDGET 200000, fail-closed) IS implemented in worktree ~/src/DOG-015 (git/IGNO.c), UNLANDED.