@@ -95,6 +95,89 @@ TEST(TestPhraseMatch, TestComplex)
9595 run (" nonsense" , nullptr );
9696}
9797
98+ TEST (TestPhraseMatch, TestWordBoundary)
99+ {
100+ std::vector<const char *> strings{" banana" , " $apple" , " orange$" , " $pear$" };
101+ std::vector<uint32_t > lengths (strings.size ());
102+ std::generate (lengths.begin (), lengths.end (),
103+ [i = 0 , &strings]() mutable { return strlen (strings[i++]); });
104+
105+ phrase_match matcher (strings, lengths, true );
106+
107+ auto run = [&matcher](const char *str, const char *expect) {
108+ ddwaf_object param;
109+ ddwaf_object_string (¶m, str);
110+ if (expect != nullptr ) {
111+ auto [res, highlight] = matcher.match (param);
112+ EXPECT_TRUE (res);
113+ EXPECT_STREQ (highlight.c_str (), expect);
114+ } else {
115+ EXPECT_FALSE (matcher.match (param).first );
116+ }
117+ ddwaf_object_free (¶m);
118+ };
119+
120+ run (" banana" , " banana" );
121+ run (" banana" , " banana" );
122+ run (" banana " , " banana" );
123+ run (" word banana word" , " banana" );
124+ run (" word ;banana/ word" , " banana" );
125+
126+ run (" banan" , nullptr );
127+ run (" abanana" , nullptr );
128+ run (" bananaa" , nullptr );
129+ run (" abananaa" , nullptr );
130+ run (" banana_" , nullptr );
131+ run (" _banana" , nullptr );
132+ run (" _banana_" , nullptr );
133+ run (" _banana " , nullptr );
134+ run (" banana_ " , nullptr );
135+ run (" _banana_ " , nullptr );
136+
137+ run (" $apple" , " $apple" );
138+ run (" s$apple" , " $apple" );
139+ run (" ;$apple" , " $apple" );
140+ run (" ;$apple;" , " $apple" );
141+ run (" $apple;" , " $apple" );
142+ run (" word $apple word" , " $apple" );
143+
144+ run (" apple" , nullptr );
145+ run (" $applea" , nullptr );
146+ run (" a$applea" , nullptr );
147+ run (" $apple_" , nullptr );
148+ run (" _$apple_" , nullptr );
149+ run (" $apple_ " , nullptr );
150+ run (" _$apple_ " , nullptr );
151+
152+ run (" orange$" , " orange$" );
153+ run (" orange$s" , " orange$" );
154+ run (" ;orange$" , " orange$" );
155+ run (" ;orange$;" , " orange$" );
156+ run (" orange$;" , " orange$" );
157+ run (" word orange$word" , " orange$" );
158+
159+ run (" orange" , nullptr );
160+ run (" aorange$" , nullptr );
161+ run (" aorange$a" , nullptr );
162+ run (" _orange$" , nullptr );
163+ run (" _orange$_" , nullptr );
164+ run (" _orange$ " , nullptr );
165+ run (" _orange$_ " , nullptr );
166+
167+ run (" $pear$" , " $pear$" );
168+ run (" $pear$s" , " $pear$" );
169+ run (" s$pear$" , " $pear$" );
170+ run (" s$pear$s" , " $pear$" );
171+ run (" ;$pear$" , " $pear$" );
172+ run (" ;$pear$;" , " $pear$" );
173+ run (" $pear$;" , " $pear$" );
174+ run (" word$pear$word" , " $pear$" );
175+ run (" word $pear$ word" , " $pear$" );
176+
177+ run (" pear$" , nullptr );
178+ run (" $pear" , nullptr );
179+ }
180+
98181TEST (TestPhraseMatch, TestInvalidInput)
99182{
100183 std::vector<const char *> strings{" aaaa" , " bbbb" , " cccc" };
0 commit comments