diff --git a/sublist/sublist.go b/sublist/sublist.go index 2d38950f..190f1cdd 100644 --- a/sublist/sublist.go +++ b/sublist/sublist.go @@ -410,6 +410,25 @@ func matchLiteral(literal, subject []byte) bool { return true } +func IsValidLiteralSubject(subject []byte) bool { + tsa := [16][]byte{} + toks := split(subject, tsa[:0]) + + for _, t := range toks { + if len(t) == 0 { + return false + } + if len(t) > 1 { + continue + } + switch t[0] { + case _PWC, _FWC: + return false + } + } + return true +} + // Count return the number of stored items in the HashMap. func (s *Sublist) Count() uint32 { return s.count } diff --git a/sublist/sublist_test.go b/sublist/sublist_test.go index e4b17aad..09109d7f 100644 --- a/sublist/sublist_test.go +++ b/sublist/sublist_test.go @@ -173,9 +173,12 @@ func TestRemoveCleanupWildcards(t *testing.T) { verifyNumLevels(s, 0, t) } -func TestMalformedSubjects(t *testing.T) { +func TestInvalidSubjectsInsert(t *testing.T) { s := New() + // Insert, or subscribtions, can have wildcards, but not empty tokens, + // and can not have a FWC that is not terminal + // beginning empty token if err := s.Insert([]byte(".foo"), '@'); err != ErrInvalidSubject { t.Fatal("Expected invalid subject error") @@ -199,7 +202,6 @@ func TestMalformedSubjects(t *testing.T) { } } - func TestCacheBehavior(t *testing.T) { s := New() literal := []byte("a.b.c") @@ -226,6 +228,17 @@ func checkBool(b, expected bool, t *testing.T) { } } +func TestValidLiteralSubjects(t *testing.T) { + checkBool(IsValidLiteralSubject([]byte("foo")), true, t) + checkBool(IsValidLiteralSubject([]byte(".foo")), false, t) + checkBool(IsValidLiteralSubject([]byte("foo.")), false, t) + checkBool(IsValidLiteralSubject([]byte("foo..bar")), false, t) + checkBool(IsValidLiteralSubject([]byte("foo.bar.*")), false, t) + checkBool(IsValidLiteralSubject([]byte("foo.bar.>")), false, t) + checkBool(IsValidLiteralSubject([]byte("*")), false, t) + checkBool(IsValidLiteralSubject([]byte(">")), false, t) +} + func TestMatchLiterals(t *testing.T) { checkBool(matchLiteral([]byte("foo"), []byte("foo")), true, t) checkBool(matchLiteral([]byte("foo"), []byte("bar")), false, t)