From bb47bb7c29eb9e59780d631772081daa42d111b7 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 9 Mar 2026 12:52:12 +0700 Subject: [PATCH] fix: handle nested brackets in rspamd symbol params --- pkg/analyzer/rspamd.go | 5 +++-- pkg/analyzer/rspamd_test.go | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/pkg/analyzer/rspamd.go b/pkg/analyzer/rspamd.go index d394c62..c2ea1cf 100644 --- a/pkg/analyzer/rspamd.go +++ b/pkg/analyzer/rspamd.go @@ -111,8 +111,9 @@ func (a *RspamdAnalyzer) parseSpamdResult(header string, result *api.RspamdResul } // Parse symbols: SYMBOL(score)[params] - // Each symbol entry is separated by ";" - symbolRe := regexp.MustCompile(`(\w+)\((-?\d+\.?\d*)\)(?:\[([^\]]*)\])?`) + // Each symbol entry is separated by ";", so within each part we use a + // greedy match to capture params that may contain nested brackets. + symbolRe := regexp.MustCompile(`(\w+)\((-?\d+\.?\d*)\)(?:\[(.*)\])?`) for _, part := range strings.Split(header, ";") { part = strings.TrimSpace(part) matches := symbolRe.FindStringSubmatch(part) diff --git a/pkg/analyzer/rspamd_test.go b/pkg/analyzer/rspamd_test.go index 180bafd..de98fe8 100644 --- a/pkg/analyzer/rspamd_test.go +++ b/pkg/analyzer/rspamd_test.go @@ -104,6 +104,26 @@ func TestParseSpamdResult(t *testing.T) { expectedIsSpam: true, expectedSymbols: map[string]float32{}, }, + { + name: "Zero threshold with symbols containing nested brackets in params", + header: "default: False [0.90 / 0.00];\n" + + "\tARC_REJECT(1.00)[cannot verify 1 of 1 signatures: {[1] = sig:mail-tester.local:signature has incorrect length: 12}];\n" + + "\tMIME_GOOD(-0.10)[multipart/alternative,text/plain];\n" + + "\tMIME_TRACE(0.00)[0:+,1:+,2:~]", + expectedScore: 0.90, + expectedThreshold: rspamdDefaultAddHeaderThreshold, + expectedIsSpam: false, + expectedSymbols: map[string]float32{ + "ARC_REJECT": 1.00, + "MIME_GOOD": -0.10, + "MIME_TRACE": 0.00, + }, + expectedSymParams: map[string]string{ + "ARC_REJECT": "cannot verify 1 of 1 signatures: {[1] = sig:mail-tester.local:signature has incorrect length: 12}", + "MIME_GOOD": "multipart/alternative,text/plain", + "MIME_TRACE": "0:+,1:+,2:~", + }, + }, } analyzer := NewRspamdAnalyzer()