From e0487b95cc312539ef9b4fc8f05bff7f73f8a828 Mon Sep 17 00:00:00 2001 From: Ivan Kozlovic Date: Thu, 28 Jan 2021 17:16:13 -0700 Subject: [PATCH] [FIXED] Return no match result if subject contains empty token A subject such as `foo..bar` is invalid, but if it is published from a connection that has disabled pedantic, then the message is matched against subscriptions and will be delivered. This change causes Sublist.Match() to return no result. Signed-off-by: Ivan Kozlovic --- server/sublist.go | 6 ++++++ server/sublist_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/server/sublist.go b/server/sublist.go index 8a019bd1..d47e91ef 100644 --- a/server/sublist.go +++ b/server/sublist.go @@ -510,10 +510,16 @@ func (s *Sublist) match(subject string, doLock bool) *SublistResult { start := 0 for i := 0; i < len(subject); i++ { if subject[i] == btsep { + if i-start == 0 { + return emptyResult + } tokens = append(tokens, subject[start:i]) start = i + 1 } } + if start >= len(subject) { + return emptyResult + } tokens = append(tokens, subject[start:]) // FIXME(dlc) - Make shared pool between sublist and client readLoop? diff --git a/server/sublist_test.go b/server/sublist_test.go index 21cb27f3..e17325cb 100644 --- a/server/sublist_test.go +++ b/server/sublist_test.go @@ -1396,6 +1396,32 @@ func TestSublistReverseMatch(t *testing.T) { verifyMember(r.psubs, fooBarBazSub, t) } +func TestSublistMatchWithEmptyTokens(t *testing.T) { + for _, test := range []struct { + name string + cache bool + }{ + {"cache", true}, + {"no cache", false}, + } { + t.Run(test.name, func(t *testing.T) { + sl := NewSublist(true) + sub1 := newSub(">") + sub2 := newQSub(">", "queue") + sl.Insert(sub1) + sl.Insert(sub2) + + for _, subj := range []string{".foo", "..foo", "foo..", "foo.", "foo..bar", "foo...bar"} { + t.Run(subj, func(t *testing.T) { + r := sl.Match(subj) + verifyLen(r.psubs, 0, t) + verifyQLen(r.qsubs, 0, t) + }) + } + }) + } +} + // -- Benchmarks Setup -- var benchSublistSubs []*subscription