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.