From d7d50ae9902d69b2e52d446684b5ab01a5ecab1e Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Fri, 17 Apr 2026 22:19:00 +0200 Subject: Reject an invalid regex when saving a match-and-replace rule internal/rules/rules.go's apply() treats a regex that fails to compile exactly the same as "no match" - it silently returns the text unchanged with no error surfaced anywhere in the call chain. rules_save had no validation before persisting, so a rule with a typo'd regex would save successfully, show as Enabled in the UI, and simply never fire on any traffic - no indication anything was wrong. internal/ipc/server.go's "rules_save" handler now compiles r.Match with regexp.Compile before persisting when IsRegex is set, rejecting with a clear "invalid regex: ..." error otherwise. No TUI changes needed: the existing ruleWriteDoneMsg error path already surfaces any saveRule error inline via the status line and - since it only clears ruleForm on success - keeps the form open with the user's draft intact so they can fix the pattern without losing their edits. That path already existed for other error classes (DB errors); this just adds a new one flowing through it. Verified live over the real protocol (raw JSON on the control socket): an unclosed-bracket regex is rejected with the expected error and never reaches the rules table; a valid regex rule still saves and returns normally. go build/vet/gofmt/test/mod tidy all clean. --- internal/ipc/server.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/ipc/server.go b/internal/ipc/server.go index 9602912..94073da 100644 --- a/internal/ipc/server.go +++ b/internal/ipc/server.go @@ -229,6 +229,18 @@ func (s *Server) handleConn(conn net.Conn) { continue } r := *req.Rule + // A rule with a regex that fails to compile silently never + // matches anything at apply time (rules.apply treats a + // compile error the same as "no match") - the user would see + // it saved and enabled with no indication it's actually + // inert. Reject it here instead, at the point they can still + // fix it. + if r.IsRegex { + if _, err := regexp.Compile(r.Match); err != nil { + enc.Encode(Response{Type: "error", Error: "invalid regex: " + err.Error()}) + continue + } + } var err error if r.ID == 0 { r.ID, err = s.db.AddRule(r) -- cgit v1.2.3