From 1311cf38d49e2969502ee2195f6095046137aee8 Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Sat, 26 Sep 2026 10:53:52 -0700 Subject: [PATCH] pdfdoc test: RE2 timing bound 1 s -> 10 s (race detector made it flaky: 1.0-1.9 s) The check distinguishes linear time from catastrophic backtracking, which would never finish on a 1 MB input, so a generous bound loses nothing. Reported by talos. Co-Authored-By: Claude Opus 5.5 --- docs/plans/p5a/_files/internal/pdfdoc/pdfdoc_test.go | 7 +++++-- internal/pdfdoc/pdfdoc_test.go | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/plans/p5a/_files/internal/pdfdoc/pdfdoc_test.go b/docs/plans/p5a/_files/internal/pdfdoc/pdfdoc_test.go index 47bb287..a0c2d1f 100644 --- a/docs/plans/p5a/_files/internal/pdfdoc/pdfdoc_test.go +++ b/docs/plans/p5a/_files/internal/pdfdoc/pdfdoc_test.go @@ -234,11 +234,14 @@ func TestGrepLimits(t *testing.T) { if _, err := pdfdoc.Render(d, pdfdoc.Options{Grep: "(unclosed", OutCap: 1000}); !errors.Is(err, pdfdoc.ErrBadGrep) { t.Errorf("bad regexp: %v, want ErrBadGrep", err) } - // RE2 is linear: the classic catastrophic pattern over a 1 MB page finishes quickly. + // RE2 is linear: the classic catastrophic pattern over a 1 MB page finishes. A backtracking + // engine would not finish at all on this input, so the bound only has to be finite and far + // above normal: 10 s. (1 s was too tight under -race, which slows regexp ~15–20x: talos + // measured 1.5–1.9 s, 2026-09-26.) evil := &pdftext.Doc{Meta: pdftext.Meta{Pages: 1}, Text: []string{strings.Repeat("a", 1<<20) + "!"}} start := time.Now() _, _ = pdfdoc.Render(evil, pdfdoc.Options{Grep: "(a+)+$", OutCap: 1000}) - if d := time.Since(start); d > time.Second { + if d := time.Since(start); d > 10*time.Second { t.Errorf("(a+)+$ took %v", d) } // Output stays under the cap. diff --git a/internal/pdfdoc/pdfdoc_test.go b/internal/pdfdoc/pdfdoc_test.go index 47bb287..a0c2d1f 100644 --- a/internal/pdfdoc/pdfdoc_test.go +++ b/internal/pdfdoc/pdfdoc_test.go @@ -234,11 +234,14 @@ func TestGrepLimits(t *testing.T) { if _, err := pdfdoc.Render(d, pdfdoc.Options{Grep: "(unclosed", OutCap: 1000}); !errors.Is(err, pdfdoc.ErrBadGrep) { t.Errorf("bad regexp: %v, want ErrBadGrep", err) } - // RE2 is linear: the classic catastrophic pattern over a 1 MB page finishes quickly. + // RE2 is linear: the classic catastrophic pattern over a 1 MB page finishes. A backtracking + // engine would not finish at all on this input, so the bound only has to be finite and far + // above normal: 10 s. (1 s was too tight under -race, which slows regexp ~15–20x: talos + // measured 1.5–1.9 s, 2026-09-26.) evil := &pdftext.Doc{Meta: pdftext.Meta{Pages: 1}, Text: []string{strings.Repeat("a", 1<<20) + "!"}} start := time.Now() _, _ = pdfdoc.Render(evil, pdfdoc.Options{Grep: "(a+)+$", OutCap: 1000}) - if d := time.Since(start); d > time.Second { + if d := time.Since(start); d > 10*time.Second { t.Errorf("(a+)+$ took %v", d) } // Output stays under the cap.