diff --git a/assert/assertions.go b/assert/assertions.go index 6950636d3..64857c6ef 100644 --- a/assert/assertions.go +++ b/assert/assertions.go @@ -1708,21 +1708,25 @@ func ErrorContains(t TestingT, theError error, contains string, msgAndArgs ...in } // matchRegexp return true if a specified regexp matches a string. -func matchRegexp(rx interface{}, str interface{}) bool { +func matchRegexp(rx interface{}, str interface{}) (bool, error) { var r *regexp.Regexp if rr, ok := rx.(*regexp.Regexp); ok { r = rr } else { - r = regexp.MustCompile(fmt.Sprint(rx)) + var err error + r, err = regexp.Compile(fmt.Sprint(rx)) + if err != nil { + return false, err + } } switch v := str.(type) { case []byte: - return r.Match(v) + return r.Match(v), nil case string: - return r.MatchString(v) + return r.MatchString(v), nil default: - return r.MatchString(fmt.Sprint(v)) + return r.MatchString(fmt.Sprint(v)), nil } } @@ -1735,7 +1739,11 @@ func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface h.Helper() } - match := matchRegexp(rx, str) + match, err := matchRegexp(rx, str) + if err != nil { + Fail(t, fmt.Sprintf("Invalid regexp \"%v\": %s", rx, err), msgAndArgs...) + return false + } if !match { Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) @@ -1752,7 +1760,11 @@ func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interf if h, ok := t.(tHelper); ok { h.Helper() } - match := matchRegexp(rx, str) + match, err := matchRegexp(rx, str) + if err != nil { + Fail(t, fmt.Sprintf("Invalid regexp \"%v\": %s", rx, err), msgAndArgs...) + return false + } if match { Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) diff --git a/assert/assertions_test.go b/assert/assertions_test.go index 4975f5e41..d5f3a7a6f 100644 --- a/assert/assertions_test.go +++ b/assert/assertions_test.go @@ -2557,6 +2557,21 @@ func TestRegexp(t *testing.T) { } } +func TestRegexpWithInvalidRegex(t *testing.T) { + // Issue #1794: Regexp should fail gracefully on invalid regex, not panic + t.Parallel() + + mockT := new(testing.T) + + // Should not panic; should return false (assertion fails) + False(t, Regexp(mockT, `\C`, "any string")) + False(t, NotRegexp(mockT, `\C`, "any string")) + + // Another invalid pattern + False(t, Regexp(mockT, `(?P[)`, "test")) + False(t, NotRegexp(mockT, `(?P[)`, "test")) +} + func testAutogeneratedFunction() { defer func() { if err := recover(); err == nil {