1 /*
2 * Copyright (c) 2015-2017, Intel Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * * Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Intel Corporation nor the names of its contributors
13 * may be used to endorse or promote products derived from this software
14 * without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "config.h"
30
31 #include "gtest/gtest.h"
32 #include "hs.h"
33 #include "test_util.h"
34
35 static char garbage[] = "TEST(HyperscanArgChecks, DatabaseSizeNoDatabase) {" \
36 " size_t sz = hs_database_size(0);" \
37 " ASSERT_EQ(0, sz);";
38
39 static unsigned lastMatchId = 0;
40 static unsigned long long lastMatchFrom = 0;
41 static unsigned long long lastMatchTo = 0;
42 static unsigned lastMatchFlags = 0;
43 static void *lastMatchCtx = nullptr;
44
45 // Single match callback: record all the details from a single match
46 static
singleHandler(unsigned id,unsigned long long from,unsigned long long to,unsigned flags,void * ctx)47 int singleHandler(unsigned id, unsigned long long from,
48 unsigned long long to, unsigned flags, void *ctx) {
49 lastMatchId = id;
50 lastMatchFrom = from;
51 lastMatchTo = to;
52 lastMatchFlags = flags;
53 lastMatchCtx = ctx;
54 return 0;
55 }
56
57 namespace /* anonymous */ {
58
59 // Break the magic number of the given database.
breakDatabaseMagic(hs_database * db)60 void breakDatabaseMagic(hs_database *db) {
61 // database magic should be 0xdbdb at the start
62 ASSERT_TRUE(memcmp("\xdb\xdb", db, 2) == 0);
63 *(char *)db = 0xdc;
64 }
65
66 // Break the version number of the given database.
breakDatabaseVersion(hs_database * db)67 void breakDatabaseVersion(hs_database *db) {
68 // database version is the second u32
69 *((char *)db + 4) += 1;
70 }
71
72 // Break the platform data of the given database.
breakDatabasePlatform(hs_database * db)73 void breakDatabasePlatform(hs_database *db) {
74 // database platform is an aligned u64a 16 bytes in
75 memset((char *)db + 16, 0xff, 8);
76 }
77
78 // Break the alignment of the bytecode for the given database.
breakDatabaseBytecode(hs_database * db)79 void breakDatabaseBytecode(hs_database *db) {
80 // bytecode ptr is a u32, 36 bytes in
81 unsigned int *bytecode = (unsigned int *)((char *)db + 36);
82 ASSERT_NE(0U, *bytecode);
83 ASSERT_EQ(0U, (size_t)((char *)db + *bytecode) % 16U);
84 *bytecode += 3;
85 }
86
87 // Check that hs_valid_platform says we can run here
TEST(HyperscanArgChecks,ValidPlatform)88 TEST(HyperscanArgChecks, ValidPlatform) {
89 hs_error_t error = hs_valid_platform();
90 ASSERT_EQ(HS_SUCCESS, error) << "hs_valid_platform should return zero";
91 }
92
93 // Check that hs_version gives us a reasonable string back
TEST(HyperscanArgChecks,Version)94 TEST(HyperscanArgChecks, Version) {
95 const char *version = hs_version();
96 ASSERT_TRUE(version != nullptr);
97 ASSERT_TRUE(version[0] >= '0' && version[0] <= '9') << "First byte should be a digit.";
98 ASSERT_EQ('.', version[1]) << "Second byte should be a dot.";
99 }
100
101 // hs_compile: Compile a NULL pattern (block mode)
TEST(HyperscanArgChecks,SingleCompileBlockNoPattern)102 TEST(HyperscanArgChecks, SingleCompileBlockNoPattern) {
103 hs_database_t *db = nullptr;
104 hs_compile_error_t *compile_err = nullptr;
105 hs_error_t err = hs_compile(nullptr, 0, HS_MODE_NOSTREAM, nullptr, &db,
106 &compile_err);
107 EXPECT_EQ(HS_COMPILER_ERROR, err);
108 EXPECT_TRUE(db == nullptr);
109 EXPECT_TRUE(compile_err != nullptr);
110 hs_free_compile_error(compile_err);
111 }
112
113 // hs_compile: Compile a NULL pattern (streaming mode)
TEST(HyperscanArgChecks,SingleCompileStreamingNoPattern)114 TEST(HyperscanArgChecks, SingleCompileStreamingNoPattern) {
115 hs_database_t *db = nullptr;
116 hs_compile_error_t *compile_err = nullptr;
117 hs_error_t err = hs_compile(nullptr, 0, HS_MODE_STREAM, nullptr, &db,
118 &compile_err);
119 EXPECT_EQ(HS_COMPILER_ERROR, err);
120 EXPECT_TRUE(db == nullptr);
121 EXPECT_TRUE(compile_err != nullptr);
122 hs_free_compile_error(compile_err);
123 }
124
125 // hs_compile: Compile a pattern to a NULL database ptr (block mode)
TEST(HyperscanArgChecks,SingleCompileBlockNoDatabase)126 TEST(HyperscanArgChecks, SingleCompileBlockNoDatabase) {
127 hs_compile_error_t *compile_err = nullptr;
128 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, nullptr,
129 &compile_err);
130 EXPECT_EQ(HS_COMPILER_ERROR, err);
131 EXPECT_TRUE(compile_err != nullptr);
132 hs_free_compile_error(compile_err);
133 }
134
135 // hs_compile: Compile a pattern to a NULL database ptr (streaming mode)
TEST(HyperscanArgChecks,SingleCompileStreamingNoDatabase)136 TEST(HyperscanArgChecks, SingleCompileStreamingNoDatabase) {
137 hs_compile_error_t *compile_err = nullptr;
138 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, nullptr,
139 &compile_err);
140 EXPECT_EQ(HS_COMPILER_ERROR, err);
141 EXPECT_TRUE(compile_err != nullptr);
142 hs_free_compile_error(compile_err);
143 }
144
145 // hs_compile: Compile a pattern with no mode set
TEST(HyperscanArgChecks,SingleCompileNoMode)146 TEST(HyperscanArgChecks, SingleCompileNoMode) {
147 hs_database_t *db = nullptr;
148 hs_compile_error_t *compile_err = nullptr;
149 hs_error_t err = hs_compile("foobar", 0, 0, nullptr, &db, &compile_err);
150 EXPECT_EQ(HS_COMPILER_ERROR, err);
151 EXPECT_TRUE(compile_err != nullptr);
152 hs_free_compile_error(compile_err);
153 }
154
155 // hs_compile: Compile a pattern with several modes set
TEST(HyperscanArgChecks,SingleCompileSeveralModes1)156 TEST(HyperscanArgChecks, SingleCompileSeveralModes1) {
157 hs_database_t *db = nullptr;
158 hs_compile_error_t *compile_err = nullptr;
159 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM | HS_MODE_NOSTREAM,
160 nullptr, &db, &compile_err);
161 EXPECT_EQ(HS_COMPILER_ERROR, err);
162 EXPECT_TRUE(compile_err != nullptr);
163 hs_free_compile_error(compile_err);
164 }
165
166 // hs_compile: Compile a pattern with bogus flags
TEST(HyperscanArgChecks,SingleCompileBogusFlags)167 TEST(HyperscanArgChecks, SingleCompileBogusFlags) {
168 hs_database_t *db = nullptr;
169 hs_compile_error_t *compile_err = nullptr;
170 hs_error_t err = hs_compile("foobar", 0xdeadbeef, HS_MODE_NOSTREAM,
171 nullptr, &db, &compile_err);
172 EXPECT_EQ(HS_COMPILER_ERROR, err);
173 EXPECT_TRUE(compile_err != nullptr);
174 EXPECT_STREQ("only HS_FLAG_QUIET and HS_FLAG_SINGLEMATCH "
175 "are supported in combination "
176 "with HS_FLAG_COMBINATION.", compile_err->message);
177
178 hs_free_compile_error(compile_err);
179 }
180
181 // hs_compile: Compile a pattern with bogus mode flags set.
TEST(HyperscanArgChecks,SingleCompileBogusMode1)182 TEST(HyperscanArgChecks, SingleCompileBogusMode1) {
183 hs_database_t *db = nullptr;
184 hs_compile_error_t *compile_err = nullptr;
185
186 unsigned mode = HS_MODE_STREAM | (1U << 30);
187
188 hs_error_t err = hs_compile("foobar", 0, mode, nullptr, &db, &compile_err);
189 EXPECT_EQ(HS_COMPILER_ERROR, err);
190 ASSERT_TRUE(compile_err != nullptr);
191 ASSERT_STREQ("Invalid parameter: unrecognised mode flags.",
192 compile_err->message);
193 hs_free_compile_error(compile_err);
194 }
195
TEST(HyperscanArgChecks,SingleCompileBadTune)196 TEST(HyperscanArgChecks, SingleCompileBadTune) {
197 hs_database_t *db = nullptr;
198 hs_compile_error_t *compile_err = nullptr;
199 hs_platform_info_t plat;
200 plat.cpu_features = 0;
201 plat.tune = 42;
202 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, &plat, &db,
203 &compile_err);
204 EXPECT_EQ(HS_COMPILER_ERROR, err);
205 EXPECT_TRUE(compile_err != nullptr);
206 EXPECT_STREQ("Invalid tuning value specified in the platform information.",
207 compile_err->message);
208
209 hs_free_compile_error(compile_err);
210 }
211
TEST(HyperscanArgChecks,SingleCompileBadFeatures)212 TEST(HyperscanArgChecks, SingleCompileBadFeatures) {
213 hs_database_t *db = nullptr;
214 hs_compile_error_t *compile_err = nullptr;
215 hs_platform_info_t plat;
216 plat.cpu_features = 42;
217 plat.tune = 0;
218 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, &plat, &db,
219 &compile_err);
220 EXPECT_EQ(HS_COMPILER_ERROR, err);
221 EXPECT_TRUE(compile_err != nullptr);
222 EXPECT_STREQ("Invalid cpu features specified in the platform information.",
223 compile_err->message);
224
225 hs_free_compile_error(compile_err);
226 }
227
228 // hs_compile: Check SOM flag validation.
TEST(HyperscanArgChecks,SingleCompileSOMFlag)229 TEST(HyperscanArgChecks, SingleCompileSOMFlag) {
230
231 // try using the flags without a SOM mode.
232 hs_database_t *db = nullptr;
233 hs_compile_error_t *compile_err = nullptr;
234 hs_error_t err = hs_compile("foobar", HS_FLAG_SOM_LEFTMOST, HS_MODE_STREAM,
235 nullptr, &db, &compile_err);
236 ASSERT_EQ(HS_COMPILER_ERROR, err) << "should have failed with flag "
237 << HS_FLAG_SOM_LEFTMOST;
238 ASSERT_TRUE(compile_err != nullptr);
239 hs_free_compile_error(compile_err);
240 }
241
242 // hs_compile: Check SOM mode validation.
TEST(HyperscanArgChecks,SingleCompileSOMModes)243 TEST(HyperscanArgChecks, SingleCompileSOMModes) {
244 static const unsigned som_modes[] = {
245 HS_MODE_SOM_HORIZON_LARGE,
246 HS_MODE_SOM_HORIZON_MEDIUM,
247 HS_MODE_SOM_HORIZON_SMALL
248 };
249 const size_t num_modes = sizeof(som_modes)/sizeof(som_modes[0]);
250
251 // compilation of a trivial case with a single mode set should be fine.
252 for (size_t i = 0; i < num_modes; i++) {
253 hs_database_t *db = nullptr;
254 hs_compile_error_t *compile_err = nullptr;
255 hs_error_t err = hs_compile("foobar", HS_FLAG_SOM_LEFTMOST,
256 HS_MODE_STREAM | som_modes[i], nullptr, &db,
257 &compile_err);
258 ASSERT_EQ(HS_SUCCESS, err);
259 hs_free_database(db);
260 }
261
262 // you can only use one of the SOM modes at a time.
263 for (size_t i = 0; i < num_modes; i++) {
264 for (size_t j = i + 1; j < num_modes; j++) {
265 hs_database_t *db = nullptr;
266 hs_compile_error_t *compile_err = nullptr;
267 unsigned int mode = som_modes[i] | som_modes[j];
268 hs_error_t err = hs_compile("foobar", HS_FLAG_SOM_LEFTMOST,
269 HS_MODE_STREAM | mode, nullptr, &db,
270 &compile_err);
271 ASSERT_EQ(HS_COMPILER_ERROR, err)
272 << "should have failed with mode " << mode;
273 ASSERT_TRUE(compile_err != nullptr);
274 hs_free_compile_error(compile_err);
275 }
276 }
277 }
278
279 // hs_compile_multi: Compile a NULL pattern set (block mode)
TEST(HyperscanArgChecks,MultiCompileBlockNoPattern)280 TEST(HyperscanArgChecks, MultiCompileBlockNoPattern) {
281 hs_database_t *db = nullptr;
282 hs_compile_error_t *compile_err = nullptr;
283 hs_error_t err = hs_compile_multi(nullptr, nullptr, nullptr, 1, HS_MODE_NOSTREAM,
284 nullptr, &db, &compile_err);
285 EXPECT_EQ(HS_COMPILER_ERROR, err);
286 EXPECT_TRUE(db == nullptr);
287 EXPECT_TRUE(compile_err != nullptr);
288 hs_free_compile_error(compile_err);
289 }
290
291 // hs_compile_multi: Compile a NULL pattern set (streaming mode)
TEST(HyperscanArgChecks,MultiCompileStreamingNoPattern)292 TEST(HyperscanArgChecks, MultiCompileStreamingNoPattern) {
293 hs_database_t *db = nullptr;
294 hs_compile_error_t *compile_err = nullptr;
295 hs_error_t err = hs_compile_multi(nullptr, nullptr, nullptr, 1, HS_MODE_STREAM,
296 nullptr, &db, &compile_err);
297 EXPECT_EQ(HS_COMPILER_ERROR, err);
298 EXPECT_TRUE(db == nullptr);
299 EXPECT_TRUE(compile_err != nullptr);
300 hs_free_compile_error(compile_err);
301 }
302
303 // hs_compile_multi: Compile a set of zero patterns
TEST(HyperscanArgChecks,MultiCompileZeroPatterns)304 TEST(HyperscanArgChecks, MultiCompileZeroPatterns) {
305 hs_database_t *db = nullptr;
306 hs_compile_error_t *compile_err = nullptr;
307 const char *expr[] = {"foobar"};
308 hs_error_t err = hs_compile_multi(expr, nullptr, nullptr, 0, HS_MODE_NOSTREAM,
309 nullptr, &db, &compile_err);
310 EXPECT_EQ(HS_COMPILER_ERROR, err);
311 EXPECT_TRUE(db == nullptr);
312 EXPECT_TRUE(compile_err != nullptr);
313 hs_free_compile_error(compile_err);
314 }
315
316 // hs_compile_multi: Compile a pattern to a NULL database ptr (block mode)
TEST(HyperscanArgChecks,MultiCompileBlockNoDatabase)317 TEST(HyperscanArgChecks, MultiCompileBlockNoDatabase) {
318 hs_compile_error_t *compile_err = nullptr;
319 const char *expr[] = {"foobar"};
320 hs_error_t err = hs_compile_multi(expr, nullptr, nullptr, 1, HS_MODE_NOSTREAM,
321 nullptr, nullptr, &compile_err);
322 EXPECT_EQ(HS_COMPILER_ERROR, err);
323 EXPECT_TRUE(compile_err != nullptr);
324 hs_free_compile_error(compile_err);
325 }
326
327 // hs_compile_multi: Compile a pattern to a NULL database ptr (streaming mode)
TEST(HyperscanArgChecks,MultiCompileStreamingNoDatabase)328 TEST(HyperscanArgChecks, MultiCompileStreamingNoDatabase) {
329 hs_compile_error_t *compile_err = nullptr;
330 const char *expr[] = {"foobar"};
331 hs_error_t err = hs_compile_multi(expr, nullptr, nullptr, 1, HS_MODE_STREAM,
332 nullptr, nullptr, &compile_err);
333 EXPECT_EQ(HS_COMPILER_ERROR, err);
334 EXPECT_TRUE(compile_err != nullptr);
335 hs_free_compile_error(compile_err);
336 }
337
338 // hs_open_stream: Open a stream with a NULL database ptr
TEST(HyperscanArgChecks,OpenStreamNoDatabase)339 TEST(HyperscanArgChecks, OpenStreamNoDatabase) {
340 hs_stream_t *stream = nullptr;
341 hs_error_t err = hs_open_stream(nullptr, 0, &stream);
342 EXPECT_NE(HS_SUCCESS, err);
343 EXPECT_TRUE(stream == nullptr);
344 }
345
346 // hs_open_stream: Open a stream with a NULL stream ptr
TEST(HyperscanArgChecks,OpenStreamNoStreamId)347 TEST(HyperscanArgChecks, OpenStreamNoStreamId) {
348 hs_database_t *db = nullptr;
349 hs_compile_error_t *compile_err = nullptr;
350 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
351 &compile_err);
352 ASSERT_EQ(HS_SUCCESS, err);
353
354 err = hs_open_stream(db, 0, nullptr);
355 ASSERT_EQ(HS_INVALID, err);
356
357 // teardown
358 hs_free_database(db);
359 }
360
361 // hs_open_stream: Open a stream with a non-streaming database
TEST(HyperscanArgChecks,OpenStreamWithBlockDatabase)362 TEST(HyperscanArgChecks, OpenStreamWithBlockDatabase) {
363 hs_stream_t *stream = nullptr;
364 hs_database_t *db = nullptr;
365 hs_compile_error_t *compile_err = nullptr;
366 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
367 &compile_err);
368 ASSERT_EQ(HS_SUCCESS, err);
369
370 err = hs_open_stream(db, 0, &stream);
371 EXPECT_NE(HS_SUCCESS, err);
372 EXPECT_TRUE(stream == nullptr);
373
374 // teardown
375 hs_free_database(db);
376 }
377
378 // hs_open_stream: Open a stream with a broken database bytecode
TEST(HyperscanArgChecks,OpenStreamWithBrokenDatabaseBytecode)379 TEST(HyperscanArgChecks, OpenStreamWithBrokenDatabaseBytecode) {
380 hs_stream_t *stream = nullptr;
381 hs_database_t *db = nullptr;
382 hs_compile_error_t *compile_err = nullptr;
383 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
384 &compile_err);
385 ASSERT_EQ(HS_SUCCESS, err);
386
387 breakDatabaseBytecode(db);
388
389 err = hs_open_stream(db, 0, &stream);
390 EXPECT_NE(HS_SUCCESS, err);
391 EXPECT_TRUE(stream == nullptr);
392
393 // teardown
394 hs_free_database(db);
395 }
396
397 // hs_scan_stream: Call with no stream ID
TEST(HyperscanArgChecks,ScanStreamNoStreamID)398 TEST(HyperscanArgChecks, ScanStreamNoStreamID) {
399 hs_database_t *db = nullptr;
400 hs_compile_error_t *compile_err = nullptr;
401 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
402 &compile_err);
403 ASSERT_EQ(HS_SUCCESS, err);
404 ASSERT_TRUE(db != nullptr);
405 hs_scratch_t *scratch = nullptr;
406 err = hs_alloc_scratch(db, &scratch);
407 ASSERT_EQ(HS_SUCCESS, err);
408 ASSERT_TRUE(scratch != nullptr);
409
410 err = hs_scan_stream(nullptr, "data", 4, 0, scratch, dummy_cb, nullptr);
411 EXPECT_NE(HS_SUCCESS, err);
412 EXPECT_NE(HS_SCAN_TERMINATED, err);
413
414 // teardown
415 err = hs_free_scratch(scratch);
416 ASSERT_EQ(HS_SUCCESS, err);
417 hs_free_database(db);
418 }
419
420 // hs_scan_stream: Call with no data
TEST(HyperscanArgChecks,ScanStreamNoData)421 TEST(HyperscanArgChecks, ScanStreamNoData) {
422 hs_database_t *db = nullptr;
423 hs_compile_error_t *compile_err = nullptr;
424 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
425 &compile_err);
426 ASSERT_EQ(HS_SUCCESS, err);
427 ASSERT_TRUE(db != nullptr);
428 hs_scratch_t *scratch = nullptr;
429 err = hs_alloc_scratch(db, &scratch);
430 ASSERT_EQ(HS_SUCCESS, err);
431 ASSERT_TRUE(scratch != nullptr);
432 hs_stream_t *stream = nullptr;
433 err = hs_open_stream(db, 0, &stream);
434 ASSERT_EQ(HS_SUCCESS, err);
435 ASSERT_TRUE(stream != nullptr);
436
437 err = hs_scan_stream(stream, nullptr, 4, 0, scratch, dummy_cb, nullptr);
438 EXPECT_NE(HS_SUCCESS, err);
439 EXPECT_NE(HS_SCAN_TERMINATED, err);
440
441 // teardown
442 err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
443 ASSERT_EQ(HS_SUCCESS, err);
444 err = hs_free_scratch(scratch);
445 ASSERT_EQ(HS_SUCCESS, err);
446 hs_free_database(db);
447 }
448
449 // hs_scan_stream: Call with no scratch
TEST(HyperscanArgChecks,ScanStreamNoScratch)450 TEST(HyperscanArgChecks, ScanStreamNoScratch) {
451 hs_database_t *db = nullptr;
452 hs_compile_error_t *compile_err = nullptr;
453 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
454 &compile_err);
455 ASSERT_EQ(HS_SUCCESS, err);
456 ASSERT_TRUE(db != nullptr);
457 hs_scratch_t *scratch = nullptr;
458 err = hs_alloc_scratch(db, &scratch);
459 ASSERT_EQ(HS_SUCCESS, err);
460 ASSERT_TRUE(scratch != nullptr);
461 hs_stream_t *stream = nullptr;
462 err = hs_open_stream(db, 0, &stream);
463 ASSERT_EQ(HS_SUCCESS, err);
464 ASSERT_TRUE(stream != nullptr);
465
466 err = hs_scan_stream(stream, nullptr, 4, 0, scratch, dummy_cb, nullptr);
467 EXPECT_NE(HS_SUCCESS, err);
468 EXPECT_NE(HS_SCAN_TERMINATED, err);
469
470 // teardown
471 err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
472 ASSERT_EQ(HS_SUCCESS, err);
473 err = hs_free_scratch(scratch);
474 ASSERT_EQ(HS_SUCCESS, err);
475 hs_free_database(db);
476 }
477
478 // hs_close_stream: Call with no stream
TEST(HyperscanArgChecks,CloseStreamNoStream)479 TEST(HyperscanArgChecks, CloseStreamNoStream) {
480 hs_database_t *db = nullptr;
481 hs_compile_error_t *compile_err = nullptr;
482 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
483 &compile_err);
484 ASSERT_EQ(HS_SUCCESS, err);
485 ASSERT_TRUE(db != nullptr);
486 hs_scratch_t *scratch = nullptr;
487 err = hs_alloc_scratch(db, &scratch);
488 ASSERT_EQ(HS_SUCCESS, err);
489 ASSERT_TRUE(scratch != nullptr);
490
491 err = hs_close_stream(nullptr, scratch, dummy_cb, nullptr);
492 ASSERT_NE(HS_SUCCESS, err);
493
494 // teardown
495 err = hs_free_scratch(scratch);
496 ASSERT_EQ(HS_SUCCESS, err);
497 hs_free_database(db);
498 }
499
500 // hs_close_stream: Call with no scratch
TEST(HyperscanArgChecks,CloseStreamNoScratch)501 TEST(HyperscanArgChecks, CloseStreamNoScratch) {
502 hs_database_t *db = nullptr;
503 hs_compile_error_t *compile_err = nullptr;
504 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
505 &compile_err);
506 ASSERT_EQ(HS_SUCCESS, err);
507 ASSERT_TRUE(db != nullptr);
508 hs_stream_t *stream = nullptr;
509 err = hs_open_stream(db, 0, &stream);
510 ASSERT_EQ(HS_SUCCESS, err);
511 ASSERT_TRUE(stream != nullptr);
512
513 err = hs_close_stream(stream, nullptr, dummy_cb, nullptr);
514 EXPECT_NE(HS_SUCCESS, err);
515
516 // We happen to know we can free the stream here, and we do it so that
517 // this doesn't appear as a memory leak in valgrind
518 free(stream);
519
520 // teardown
521 hs_free_database(db);
522 }
523
524 // hs_close_stream: Call with no scratch and no callback (allowed)
TEST(HyperscanArgChecks,CloseStreamNoScratchNoCallback)525 TEST(HyperscanArgChecks, CloseStreamNoScratchNoCallback) {
526 hs_database_t *db = nullptr;
527 hs_compile_error_t *compile_err = nullptr;
528 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
529 &compile_err);
530 ASSERT_EQ(HS_SUCCESS, err);
531 ASSERT_TRUE(db != nullptr);
532 hs_stream_t *stream = nullptr;
533 err = hs_open_stream(db, 0, &stream);
534 ASSERT_EQ(HS_SUCCESS, err);
535 ASSERT_TRUE(stream != nullptr);
536
537 err = hs_close_stream(stream, nullptr, nullptr, nullptr);
538 EXPECT_EQ(HS_SUCCESS, err);
539
540 // teardown
541 hs_free_database(db);
542 }
543
544 // hs_close_stream_nomatch: Call with no stream
TEST(HyperscanArgChecks,CloseStreamNoMatchNoStream)545 TEST(HyperscanArgChecks, CloseStreamNoMatchNoStream) {
546 hs_database_t *db = nullptr;
547 hs_compile_error_t *compile_err = nullptr;
548 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
549 &compile_err);
550 ASSERT_EQ(HS_SUCCESS, err);
551 ASSERT_TRUE(db != nullptr);
552
553 hs_scratch_t *scratch = nullptr;
554 err = hs_alloc_scratch(db, &scratch);
555 ASSERT_EQ(HS_SUCCESS, err);
556
557 err = hs_close_stream(nullptr, scratch, nullptr, nullptr);
558 ASSERT_NE(HS_SUCCESS, err);
559
560 // teardown
561 err = hs_free_scratch(scratch);
562 ASSERT_EQ(HS_SUCCESS, err);
563 hs_free_database(db);
564 }
565
566 // hs_set_stream_context: change context
TEST(HyperscanArgChecks,ChangeStreamContext)567 TEST(HyperscanArgChecks, ChangeStreamContext) {
568 const char *str = "foobar";
569 hs_database_t *db = nullptr;
570 hs_compile_error_t *compile_err = nullptr;
571 hs_error_t err = hs_compile(str, 0, HS_MODE_STREAM, nullptr, &db,
572 &compile_err);
573 ASSERT_EQ(HS_SUCCESS, err);
574 ASSERT_TRUE(db != nullptr);
575
576 hs_scratch_t *scratch = nullptr;
577 err = hs_alloc_scratch(db, &scratch);
578 ASSERT_EQ(HS_SUCCESS, err);
579 ASSERT_TRUE(scratch != nullptr);
580
581 // we'll start with the context pointer set to the scratch space ...
582 hs_stream_t *stream = nullptr;
583 err = hs_open_stream(db, 0, &stream);
584 ASSERT_EQ(HS_SUCCESS, err);
585 ASSERT_TRUE(stream != nullptr);
586 err = hs_scan_stream(stream, str, strlen(str), 0, scratch, singleHandler,
587 (void *)scratch);
588 ASSERT_EQ(HS_SUCCESS, err);
589
590 ASSERT_EQ(lastMatchTo, strlen(str));
591 ASSERT_EQ(lastMatchCtx, scratch);
592
593 // ... and then change it to the stream ptr itself.
594 err = hs_scan_stream(stream, str, strlen(str), 0, scratch, singleHandler,
595 (void *)stream);
596 ASSERT_EQ(HS_SUCCESS, err);
597
598 ASSERT_EQ(lastMatchTo, 2*strlen(str));
599 ASSERT_EQ(lastMatchCtx, stream);
600
601 err = hs_close_stream(stream, scratch, nullptr, nullptr);
602 ASSERT_EQ(HS_SUCCESS, err);
603
604 // teardown
605 hs_free_database(db);
606 err = hs_free_scratch(scratch);
607 ASSERT_EQ(HS_SUCCESS, err);
608 }
609
610 // hs_reset_stream: Call with no stream id
TEST(HyperscanArgChecks,ResetStreamNoId)611 TEST(HyperscanArgChecks, ResetStreamNoId) {
612 hs_database_t *db = nullptr;
613 hs_compile_error_t *compile_err = nullptr;
614 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
615 &compile_err);
616 ASSERT_EQ(HS_SUCCESS, err);
617 ASSERT_TRUE(db != nullptr);
618
619 hs_scratch_t *scratch = nullptr;
620 err = hs_alloc_scratch(db, &scratch);
621 ASSERT_EQ(HS_SUCCESS, err);
622
623 err = hs_reset_stream(nullptr, 0, scratch, dummy_cb, nullptr);
624 ASSERT_EQ(HS_INVALID, err);
625 err = hs_free_scratch(scratch);
626 ASSERT_EQ(HS_SUCCESS, err);
627 hs_free_database(db);
628 }
629
630 // hs_reset_stream: Call with no scratch
TEST(HyperscanArgChecks,ResetStreamNoScratch)631 TEST(HyperscanArgChecks, ResetStreamNoScratch) {
632 hs_stream_t *stream = nullptr;
633 hs_database_t *db = nullptr;
634 hs_compile_error_t *compile_err = nullptr;
635 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
636 &compile_err);
637 ASSERT_EQ(HS_SUCCESS, err);
638 ASSERT_TRUE(db != nullptr);
639
640 err = hs_open_stream(db, 0, &stream);
641 ASSERT_EQ(HS_SUCCESS, err);
642 ASSERT_TRUE(stream != nullptr);
643
644 err = hs_reset_stream(stream, 0, nullptr, dummy_cb, nullptr);
645 ASSERT_EQ(HS_INVALID, err);
646
647 hs_scratch_t *scratch = nullptr;
648 err = hs_alloc_scratch(db, &scratch);
649 ASSERT_EQ(HS_SUCCESS, err);
650
651 hs_close_stream(stream, scratch, nullptr, nullptr);
652 err = hs_free_scratch(scratch);
653 ASSERT_EQ(HS_SUCCESS, err);
654 hs_free_database(db);
655 }
656
657 // hs_copy_stream: Call with no from_id
TEST(HyperscanArgChecks,CopyStreamNoFromId)658 TEST(HyperscanArgChecks, CopyStreamNoFromId) {
659 hs_stream_t *to;
660 hs_error_t err = hs_copy_stream(&to, nullptr);
661 ASSERT_EQ(HS_INVALID, err);
662 }
663
664 // hs_copy_stream: Call with no to_id
TEST(HyperscanArgChecks,CopyStreamNoToId)665 TEST(HyperscanArgChecks, CopyStreamNoToId) {
666 hs_stream_t *stream = nullptr;
667 hs_database_t *db = nullptr;
668 hs_compile_error_t *compile_err = nullptr;
669 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
670 &compile_err);
671 ASSERT_EQ(HS_SUCCESS, err);
672
673 err = hs_open_stream(db, 0, &stream);
674 ASSERT_EQ(HS_SUCCESS, err);
675 ASSERT_TRUE(stream != nullptr);
676
677 err = hs_copy_stream(nullptr, stream);
678 ASSERT_EQ(HS_INVALID, err);
679
680 hs_scratch_t *scratch = nullptr;
681 err = hs_alloc_scratch(db, &scratch);
682 ASSERT_EQ(HS_SUCCESS, err);
683
684 hs_close_stream(stream, scratch, nullptr, nullptr);
685 err = hs_free_scratch(scratch);
686 ASSERT_EQ(HS_SUCCESS, err);
687 hs_free_database(db);
688 }
689
TEST(HyperscanArgChecks,ResetAndCopyStreamNoToId)690 TEST(HyperscanArgChecks, ResetAndCopyStreamNoToId) {
691 hs_stream_t *stream = nullptr;
692 hs_database_t *db = nullptr;
693 hs_compile_error_t *compile_err = nullptr;
694 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
695 &compile_err);
696 ASSERT_EQ(HS_SUCCESS, err);
697
698 hs_scratch_t *scratch = nullptr;
699 err = hs_alloc_scratch(db, &scratch);
700 ASSERT_EQ(HS_SUCCESS, err);
701
702 err = hs_open_stream(db, 0, &stream);
703 ASSERT_EQ(HS_SUCCESS, err);
704 ASSERT_TRUE(stream != nullptr);
705
706 err = hs_reset_and_copy_stream(nullptr, stream, scratch, nullptr, nullptr);
707 ASSERT_EQ(HS_INVALID, err);
708
709 err = hs_close_stream(stream, scratch, nullptr, nullptr);
710 ASSERT_EQ(HS_SUCCESS, err);
711 err = hs_free_scratch(scratch);
712 ASSERT_EQ(HS_SUCCESS, err);
713 hs_free_database(db);
714 }
715
TEST(HyperscanArgChecks,ResetAndCopyStreamNoFromId)716 TEST(HyperscanArgChecks, ResetAndCopyStreamNoFromId) {
717 hs_stream_t *stream = nullptr;
718 hs_database_t *db = nullptr;
719 hs_compile_error_t *compile_err = nullptr;
720 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
721 &compile_err);
722 ASSERT_EQ(HS_SUCCESS, err);
723
724 hs_scratch_t *scratch = nullptr;
725 err = hs_alloc_scratch(db, &scratch);
726 ASSERT_EQ(HS_SUCCESS, err);
727
728 err = hs_open_stream(db, 0, &stream);
729 ASSERT_EQ(HS_SUCCESS, err);
730 ASSERT_TRUE(stream != nullptr);
731
732 err = hs_reset_and_copy_stream(stream, nullptr, scratch, nullptr, nullptr);
733 ASSERT_EQ(HS_INVALID, err);
734
735 err = hs_close_stream(stream, scratch, nullptr, nullptr);
736 ASSERT_EQ(HS_SUCCESS, err);
737 err = hs_free_scratch(scratch);
738 ASSERT_EQ(HS_SUCCESS, err);
739 hs_free_database(db);
740 }
741
TEST(HyperscanArgChecks,ResetAndCopyStreamSameToId)742 TEST(HyperscanArgChecks, ResetAndCopyStreamSameToId) {
743 hs_stream_t *stream = nullptr;
744 hs_database_t *db = nullptr;
745 hs_compile_error_t *compile_err = nullptr;
746 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
747 &compile_err);
748 ASSERT_EQ(HS_SUCCESS, err);
749
750 hs_scratch_t *scratch = nullptr;
751 err = hs_alloc_scratch(db, &scratch);
752 ASSERT_EQ(HS_SUCCESS, err);
753
754 err = hs_open_stream(db, 0, &stream);
755 ASSERT_EQ(HS_SUCCESS, err);
756 ASSERT_TRUE(stream != nullptr);
757
758 err = hs_reset_and_copy_stream(stream, stream, scratch, nullptr, nullptr);
759 ASSERT_EQ(HS_INVALID, err);
760
761 err = hs_close_stream(stream, scratch, nullptr, nullptr);
762 ASSERT_EQ(HS_SUCCESS, err);
763 err = hs_free_scratch(scratch);
764 ASSERT_EQ(HS_SUCCESS, err);
765 hs_free_database(db);
766 }
767
768 // hs_reset_and_copy_stream: You're allowed to reset and copy a stream with no
769 // scratch and no callback.
TEST(HyperscanArgChecks,ResetAndCopyStreamNoCallbackOrScratch)770 TEST(HyperscanArgChecks, ResetAndCopyStreamNoCallbackOrScratch) {
771 hs_stream_t *stream = nullptr;
772 hs_stream_t *stream_to = nullptr;
773 hs_database_t *db = nullptr;
774 hs_compile_error_t *compile_err = nullptr;
775 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
776 &compile_err);
777 ASSERT_EQ(HS_SUCCESS, err);
778
779 hs_scratch_t *scratch = nullptr;
780 err = hs_alloc_scratch(db, &scratch);
781 ASSERT_EQ(HS_SUCCESS, err);
782
783 err = hs_open_stream(db, 0, &stream);
784 ASSERT_EQ(HS_SUCCESS, err);
785
786 err = hs_open_stream(db, 0, &stream_to);
787 ASSERT_EQ(HS_SUCCESS, err);
788
789 err = hs_reset_and_copy_stream(stream_to, stream, nullptr, nullptr, nullptr);
790 ASSERT_EQ(HS_SUCCESS, err);
791
792 err = hs_close_stream(stream_to, scratch, nullptr, nullptr);
793 ASSERT_EQ(HS_SUCCESS, err);
794 err = hs_close_stream(stream, scratch, nullptr, nullptr);
795 ASSERT_EQ(HS_SUCCESS, err);
796 err = hs_free_scratch(scratch);
797 ASSERT_EQ(HS_SUCCESS, err);
798 hs_free_database(db);
799 }
800
801 // hs_reset_and_copy_stream: If you specify a callback, you must provide
802 // scratch.
TEST(HyperscanArgChecks,ResetAndCopyStreamNoScratch)803 TEST(HyperscanArgChecks, ResetAndCopyStreamNoScratch) {
804 hs_stream_t *stream = nullptr;
805 hs_stream_t *stream_to = nullptr;
806 hs_database_t *db = nullptr;
807 hs_compile_error_t *compile_err = nullptr;
808 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
809 &compile_err);
810 ASSERT_EQ(HS_SUCCESS, err);
811
812 hs_scratch_t *scratch = nullptr;
813 err = hs_alloc_scratch(db, &scratch);
814 ASSERT_EQ(HS_SUCCESS, err);
815
816 err = hs_open_stream(db, 0, &stream);
817 ASSERT_EQ(HS_SUCCESS, err);
818
819 err = hs_open_stream(db, 0, &stream_to);
820 ASSERT_EQ(HS_SUCCESS, err);
821
822 err = hs_reset_and_copy_stream(stream_to, stream, nullptr, dummy_cb,
823 nullptr);
824 ASSERT_EQ(HS_INVALID, err);
825
826 err = hs_close_stream(stream_to, scratch, nullptr, nullptr);
827 ASSERT_EQ(HS_SUCCESS, err);
828 err = hs_close_stream(stream, scratch, nullptr, nullptr);
829 ASSERT_EQ(HS_SUCCESS, err);
830 err = hs_free_scratch(scratch);
831 ASSERT_EQ(HS_SUCCESS, err);
832 hs_free_database(db);
833 }
834
TEST(HyperscanArgChecks,ResetAndCopyStreamDiffDb)835 TEST(HyperscanArgChecks, ResetAndCopyStreamDiffDb) {
836 hs_stream_t *stream = nullptr;
837 hs_stream_t *stream_to = nullptr;
838 hs_database_t *db = nullptr;
839 hs_database_t *db2 = nullptr;
840 hs_compile_error_t *compile_err = nullptr;
841 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
842 &compile_err);
843 ASSERT_EQ(HS_SUCCESS, err);
844
845 err = hs_compile("barfoo", 0, HS_MODE_STREAM, nullptr, &db2, &compile_err);
846 ASSERT_EQ(HS_SUCCESS, err);
847
848 hs_scratch_t *scratch = nullptr;
849 err = hs_alloc_scratch(db, &scratch);
850 ASSERT_EQ(HS_SUCCESS, err);
851 err = hs_alloc_scratch(db2, &scratch);
852 ASSERT_EQ(HS_SUCCESS, err);
853
854 err = hs_open_stream(db, 0, &stream);
855 ASSERT_EQ(HS_SUCCESS, err);
856
857 err = hs_open_stream(db2, 0, &stream_to);
858 ASSERT_EQ(HS_SUCCESS, err);
859
860 err = hs_reset_and_copy_stream(stream_to, stream, scratch, nullptr,
861 nullptr);
862 ASSERT_EQ(HS_INVALID, err);
863
864 err = hs_close_stream(stream_to, scratch, nullptr, nullptr);
865 ASSERT_EQ(HS_SUCCESS, err);
866 err = hs_close_stream(stream, scratch, nullptr, nullptr);
867 ASSERT_EQ(HS_SUCCESS, err);
868 err = hs_free_scratch(scratch);
869 ASSERT_EQ(HS_SUCCESS, err);
870 hs_free_database(db);
871 hs_free_database(db2);
872 }
873
874 // hs_scan: Call with no database
TEST(HyperscanArgChecks,ScanBlockNoDatabase)875 TEST(HyperscanArgChecks, ScanBlockNoDatabase) {
876 hs_database_t *db = nullptr;
877 hs_compile_error_t *compile_err = nullptr;
878 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
879 &compile_err);
880 ASSERT_EQ(HS_SUCCESS, err);
881 ASSERT_TRUE(db != nullptr);
882 hs_scratch_t *scratch = nullptr;
883 err = hs_alloc_scratch(db, &scratch);
884 ASSERT_EQ(HS_SUCCESS, err);
885 ASSERT_TRUE(scratch != nullptr);
886 err = hs_scan(nullptr, "data", 4, 0, scratch, dummy_cb, nullptr);
887 ASSERT_NE(HS_SUCCESS, err);
888 EXPECT_NE(HS_SCAN_TERMINATED, err);
889
890 // teardown
891 err = hs_free_scratch(scratch);
892 ASSERT_EQ(HS_SUCCESS, err);
893 hs_free_database(db);
894 }
895
896 // hs_scan: Call with a database with broken magic
TEST(HyperscanArgChecks,ScanBlockBrokenDatabaseMagic)897 TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseMagic) {
898 hs_database_t *db = nullptr;
899 hs_compile_error_t *compile_err = nullptr;
900 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
901 &compile_err);
902 ASSERT_EQ(HS_SUCCESS, err);
903 ASSERT_TRUE(db != nullptr);
904 hs_scratch_t *scratch = nullptr;
905 err = hs_alloc_scratch(db, &scratch);
906 ASSERT_EQ(HS_SUCCESS, err);
907 ASSERT_TRUE(scratch != nullptr);
908
909 // break the database here, after scratch alloc
910 breakDatabaseMagic(db);
911
912 err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
913 ASSERT_EQ(HS_INVALID, err);
914
915 // teardown
916 err = hs_free_scratch(scratch);
917 ASSERT_EQ(HS_SUCCESS, err);
918 free(db);
919 }
920
921 // hs_scan: Call with a database with broken version
TEST(HyperscanArgChecks,ScanBlockBrokenDatabaseVersion)922 TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseVersion) {
923 hs_database_t *db = nullptr;
924 hs_compile_error_t *compile_err = nullptr;
925 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
926 &compile_err);
927 ASSERT_EQ(HS_SUCCESS, err);
928 ASSERT_TRUE(db != nullptr);
929 hs_scratch_t *scratch = nullptr;
930 err = hs_alloc_scratch(db, &scratch);
931 ASSERT_EQ(HS_SUCCESS, err);
932 ASSERT_TRUE(scratch != nullptr);
933
934 // break the database here, after scratch alloc
935 breakDatabaseVersion(db);
936
937 err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
938 ASSERT_EQ(HS_DB_VERSION_ERROR, err);
939
940 // teardown
941 err = hs_free_scratch(scratch);
942 ASSERT_EQ(HS_SUCCESS, err);
943 hs_free_database(db);
944 }
945
946 // hs_scan: Call with a database with broken bytecode offset
TEST(HyperscanArgChecks,ScanBlockBrokenDatabaseBytecode)947 TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseBytecode) {
948 hs_database_t *db = nullptr;
949 hs_compile_error_t *compile_err = nullptr;
950 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
951 &compile_err);
952 ASSERT_EQ(HS_SUCCESS, err);
953 ASSERT_TRUE(db != nullptr);
954 hs_scratch_t *scratch = nullptr;
955 err = hs_alloc_scratch(db, &scratch);
956 ASSERT_EQ(HS_SUCCESS, err);
957 ASSERT_TRUE(scratch != nullptr);
958
959 // break the database here, after scratch alloc
960 breakDatabaseBytecode(db);
961
962 err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
963 ASSERT_EQ(HS_INVALID, err);
964
965 // teardown
966 err = hs_free_scratch(scratch);
967 ASSERT_EQ(HS_SUCCESS, err);
968 hs_free_database(db);
969 }
970
971 // hs_scan: Call with a database built for streaming mode
TEST(HyperscanArgChecks,ScanBlockStreamingDatabase)972 TEST(HyperscanArgChecks, ScanBlockStreamingDatabase) {
973 hs_database_t *db = nullptr;
974 hs_compile_error_t *compile_err = nullptr;
975 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
976 &compile_err);
977 ASSERT_EQ(HS_SUCCESS, err);
978 ASSERT_TRUE(db != nullptr);
979 hs_scratch_t *scratch = nullptr;
980 err = hs_alloc_scratch(db, &scratch);
981 ASSERT_EQ(HS_SUCCESS, err);
982 ASSERT_TRUE(scratch != nullptr);
983
984 err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
985 ASSERT_EQ(HS_DB_MODE_ERROR, err);
986
987 // teardown
988 err = hs_free_scratch(scratch);
989 ASSERT_EQ(HS_SUCCESS, err);
990 hs_free_database(db);
991 }
992
TEST(HyperscanArgChecks,ScanBlockVectoredDatabase)993 TEST(HyperscanArgChecks, ScanBlockVectoredDatabase) {
994 hs_database_t *db = nullptr;
995 hs_compile_error_t *compile_err = nullptr;
996 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
997 &compile_err);
998 ASSERT_EQ(HS_SUCCESS, err);
999 ASSERT_TRUE(db != nullptr);
1000 hs_scratch_t *scratch = nullptr;
1001 err = hs_alloc_scratch(db, &scratch);
1002 ASSERT_EQ(HS_SUCCESS, err);
1003 ASSERT_TRUE(scratch != nullptr);
1004
1005 err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
1006 ASSERT_EQ(HS_DB_MODE_ERROR, err);
1007
1008 // teardown
1009 err = hs_free_scratch(scratch);
1010 ASSERT_EQ(HS_SUCCESS, err);
1011 hs_free_database(db);
1012 }
1013
1014
1015 // hs_scan: Call with no data
TEST(HyperscanArgChecks,ScanBlockNoData)1016 TEST(HyperscanArgChecks, ScanBlockNoData) {
1017 hs_database_t *db = nullptr;
1018 hs_compile_error_t *compile_err = nullptr;
1019 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1020 &compile_err);
1021 ASSERT_EQ(HS_SUCCESS, err);
1022 ASSERT_TRUE(db != nullptr);
1023 hs_scratch_t *scratch = nullptr;
1024 err = hs_alloc_scratch(db, &scratch);
1025 ASSERT_EQ(HS_SUCCESS, err);
1026 ASSERT_TRUE(scratch != nullptr);
1027 err = hs_scan(db, nullptr, 4, 0, scratch, dummy_cb, nullptr);
1028 ASSERT_NE(HS_SUCCESS, err);
1029 EXPECT_NE(HS_SCAN_TERMINATED, err);
1030
1031 // teardown
1032 err = hs_free_scratch(scratch);
1033 ASSERT_EQ(HS_SUCCESS, err);
1034 hs_free_database(db);
1035 }
1036
1037 // hs_scan: Call with no scratch
TEST(HyperscanArgChecks,ScanBlockNoScratch)1038 TEST(HyperscanArgChecks, ScanBlockNoScratch) {
1039 hs_database_t *db = nullptr;
1040 hs_compile_error_t *compile_err = nullptr;
1041 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1042 &compile_err);
1043 ASSERT_EQ(HS_SUCCESS, err);
1044 ASSERT_TRUE(db != nullptr);
1045 err = hs_scan(db, "data", 4, 0, nullptr, dummy_cb, nullptr);
1046 ASSERT_NE(HS_SUCCESS, err);
1047 EXPECT_NE(HS_SCAN_TERMINATED, err);
1048
1049 // teardown
1050 hs_free_database(db);
1051 }
1052
1053 // hs_scan: Call with no event handler
TEST(HyperscanArgChecks,ScanBlockNoHandler)1054 TEST(HyperscanArgChecks, ScanBlockNoHandler) {
1055 hs_database_t *db = nullptr;
1056 hs_compile_error_t *compile_err = nullptr;
1057 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1058 &compile_err);
1059 ASSERT_EQ(HS_SUCCESS, err);
1060 ASSERT_TRUE(db != nullptr);
1061 hs_scratch_t *scratch = nullptr;
1062 err = hs_alloc_scratch(db, &scratch);
1063 ASSERT_EQ(HS_SUCCESS, err);
1064 ASSERT_TRUE(scratch != nullptr);
1065 err = hs_scan(db, "data", 4, 0, scratch, nullptr, nullptr);
1066 ASSERT_EQ(HS_SUCCESS, err);
1067 EXPECT_NE(HS_SCAN_TERMINATED, err);
1068
1069 // teardown
1070 err = hs_free_scratch(scratch);
1071 ASSERT_EQ(HS_SUCCESS, err);
1072 hs_free_database(db);
1073 }
1074
1075 // hs_scan_vector: Call with no database
TEST(HyperscanArgChecks,ScanVectorNoDatabase)1076 TEST(HyperscanArgChecks, ScanVectorNoDatabase) {
1077 hs_database_t *db = nullptr;
1078 hs_compile_error_t *compile_err = nullptr;
1079 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1080 &compile_err);
1081 ASSERT_EQ(HS_SUCCESS, err);
1082 ASSERT_TRUE(db != nullptr);
1083 hs_scratch_t *scratch = nullptr;
1084 err = hs_alloc_scratch(db, &scratch);
1085 ASSERT_EQ(HS_SUCCESS, err);
1086 ASSERT_TRUE(scratch != nullptr);
1087 const char *data[] = {"data", "data"};
1088 unsigned int len[] = {4, 4};
1089 err = hs_scan_vector(nullptr, data, len, 2, 0, scratch, dummy_cb, nullptr);
1090 ASSERT_NE(HS_SUCCESS, err);
1091 EXPECT_NE(HS_SCAN_TERMINATED, err);
1092
1093 // teardown
1094 err = hs_free_scratch(scratch);
1095 ASSERT_EQ(HS_SUCCESS, err);
1096 hs_free_database(db);
1097 }
1098
1099 // hs_scan_vector: Call with a database with broken magic
TEST(HyperscanArgChecks,ScanVectorBrokenDatabaseMagic)1100 TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseMagic) {
1101 hs_database_t *db = nullptr;
1102 hs_compile_error_t *compile_err = nullptr;
1103 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1104 &compile_err);
1105 ASSERT_EQ(HS_SUCCESS, err);
1106 ASSERT_TRUE(db != nullptr);
1107 hs_scratch_t *scratch = nullptr;
1108 err = hs_alloc_scratch(db, &scratch);
1109 ASSERT_EQ(HS_SUCCESS, err);
1110 ASSERT_TRUE(scratch != nullptr);
1111
1112 // break the database here, after scratch alloc
1113 breakDatabaseMagic(db);
1114
1115 const char *data[] = {"data", "data"};
1116 unsigned int len[] = {4, 4};
1117 err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
1118 ASSERT_EQ(HS_INVALID, err);
1119
1120 // teardown
1121 err = hs_free_scratch(scratch);
1122 ASSERT_EQ(HS_SUCCESS, err);
1123 free(db);
1124 }
1125
1126 // hs_scan_vector: Call with a database with broken version
TEST(HyperscanArgChecks,ScanVectorBrokenDatabaseVersion)1127 TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseVersion) {
1128 hs_database_t *db = nullptr;
1129 hs_compile_error_t *compile_err = nullptr;
1130 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1131 &compile_err);
1132 ASSERT_EQ(HS_SUCCESS, err);
1133 ASSERT_TRUE(db != nullptr);
1134 hs_scratch_t *scratch = nullptr;
1135 err = hs_alloc_scratch(db, &scratch);
1136 ASSERT_EQ(HS_SUCCESS, err);
1137 ASSERT_TRUE(scratch != nullptr);
1138
1139 // break the database here, after scratch alloc
1140 breakDatabaseVersion(db);
1141
1142 const char *data[] = {"data", "data"};
1143 unsigned int len[] = {4, 4};
1144 err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
1145 ASSERT_EQ(HS_DB_VERSION_ERROR, err);
1146
1147 // teardown
1148 err = hs_free_scratch(scratch);
1149 ASSERT_EQ(HS_SUCCESS, err);
1150 hs_free_database(db);
1151 }
1152
1153 // hs_scan_vector: Call with a database with broken bytecode offset
TEST(HyperscanArgChecks,ScanVectorBrokenDatabaseBytecode)1154 TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseBytecode) {
1155 hs_database_t *db = nullptr;
1156 hs_compile_error_t *compile_err = nullptr;
1157 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1158 &compile_err);
1159 ASSERT_EQ(HS_SUCCESS, err);
1160 ASSERT_TRUE(db != nullptr);
1161 hs_scratch_t *scratch = nullptr;
1162 err = hs_alloc_scratch(db, &scratch);
1163 ASSERT_EQ(HS_SUCCESS, err);
1164 ASSERT_TRUE(scratch != nullptr);
1165
1166 // break the database here, after scratch alloc
1167 breakDatabaseBytecode(db);
1168
1169 const char *data[] = {"data", "data"};
1170 unsigned int len[] = {4, 4};
1171 err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
1172 ASSERT_EQ(HS_INVALID, err);
1173
1174 // teardown
1175 err = hs_free_scratch(scratch);
1176 ASSERT_EQ(HS_SUCCESS, err);
1177 hs_free_database(db);
1178 }
1179
1180 // hs_scan_vector: Call with a database built for streaming mode
TEST(HyperscanArgChecks,ScanVectorStreamingDatabase)1181 TEST(HyperscanArgChecks, ScanVectorStreamingDatabase) {
1182 hs_database_t *db = nullptr;
1183 hs_compile_error_t *compile_err = nullptr;
1184 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
1185 &compile_err);
1186 ASSERT_EQ(HS_SUCCESS, err);
1187 ASSERT_TRUE(db != nullptr);
1188 hs_scratch_t *scratch = nullptr;
1189 err = hs_alloc_scratch(db, &scratch);
1190 ASSERT_EQ(HS_SUCCESS, err);
1191 ASSERT_TRUE(scratch != nullptr);
1192
1193 const char *data[] = {"data", "data"};
1194 unsigned int len[] = {4, 4};
1195 err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
1196 ASSERT_EQ(HS_DB_MODE_ERROR, err);
1197
1198 // teardown
1199 err = hs_free_scratch(scratch);
1200 ASSERT_EQ(HS_SUCCESS, err);
1201 hs_free_database(db);
1202 }
1203
TEST(HyperscanArgChecks,ScanVectorBlockDatabase)1204 TEST(HyperscanArgChecks, ScanVectorBlockDatabase) {
1205 hs_database_t *db = nullptr;
1206 hs_compile_error_t *compile_err = nullptr;
1207 hs_error_t err = hs_compile("foobar", 0, HS_MODE_BLOCK, nullptr, &db,
1208 &compile_err);
1209 ASSERT_EQ(HS_SUCCESS, err);
1210 ASSERT_TRUE(db != nullptr);
1211 hs_scratch_t *scratch = nullptr;
1212 err = hs_alloc_scratch(db, &scratch);
1213 ASSERT_EQ(HS_SUCCESS, err);
1214 ASSERT_TRUE(scratch != nullptr);
1215
1216 const char *data[] = {"data", "data"};
1217 unsigned int len[] = {4, 4};
1218 err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
1219 ASSERT_EQ(HS_DB_MODE_ERROR, err);
1220
1221 // teardown
1222 err = hs_free_scratch(scratch);
1223 ASSERT_EQ(HS_SUCCESS, err);
1224 hs_free_database(db);
1225 }
1226
1227 // hs_scan_vector: Call with null data
TEST(HyperscanArgChecks,ScanVectorNoDataArray)1228 TEST(HyperscanArgChecks, ScanVectorNoDataArray) {
1229 hs_database_t *db = nullptr;
1230 hs_compile_error_t *compile_err = nullptr;
1231 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1232 &compile_err);
1233 ASSERT_EQ(HS_SUCCESS, err);
1234 ASSERT_TRUE(db != nullptr);
1235 hs_scratch_t *scratch = nullptr;
1236 err = hs_alloc_scratch(db, &scratch);
1237 ASSERT_EQ(HS_SUCCESS, err);
1238 ASSERT_TRUE(scratch != nullptr);
1239
1240 unsigned int len[] = {4, 4};
1241 err = hs_scan_vector(db, nullptr, len, 2, 0, scratch, dummy_cb, nullptr);
1242 ASSERT_NE(HS_SUCCESS, err);
1243 EXPECT_NE(HS_SCAN_TERMINATED, err);
1244
1245 // teardown
1246 err = hs_free_scratch(scratch);
1247 ASSERT_EQ(HS_SUCCESS, err);
1248 hs_free_database(db);
1249 }
1250
TEST(HyperscanArgChecks,ScanVectorNoDataBlock)1251 TEST(HyperscanArgChecks, ScanVectorNoDataBlock) {
1252 hs_database_t *db = nullptr;
1253 hs_compile_error_t *compile_err = nullptr;
1254 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1255 &compile_err);
1256 ASSERT_EQ(HS_SUCCESS, err);
1257 ASSERT_TRUE(db != nullptr);
1258 hs_scratch_t *scratch = nullptr;
1259 err = hs_alloc_scratch(db, &scratch);
1260 ASSERT_EQ(HS_SUCCESS, err);
1261 ASSERT_TRUE(scratch != nullptr);
1262
1263 const char *data[] = {"data", nullptr};
1264 unsigned int len[] = {4, 4};
1265 err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
1266 ASSERT_NE(HS_SUCCESS, err);
1267 EXPECT_NE(HS_SCAN_TERMINATED, err);
1268
1269 // teardown
1270 err = hs_free_scratch(scratch);
1271 ASSERT_EQ(HS_SUCCESS, err);
1272 hs_free_database(db);
1273 }
1274
TEST(HyperscanArgChecks,ScanVectorNoLenArray)1275 TEST(HyperscanArgChecks, ScanVectorNoLenArray) {
1276 hs_database_t *db = nullptr;
1277 hs_compile_error_t *compile_err = nullptr;
1278 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1279 &compile_err);
1280 ASSERT_EQ(HS_SUCCESS, err);
1281 ASSERT_TRUE(db != nullptr);
1282 hs_scratch_t *scratch = nullptr;
1283 err = hs_alloc_scratch(db, &scratch);
1284 ASSERT_EQ(HS_SUCCESS, err);
1285 ASSERT_TRUE(scratch != nullptr);
1286
1287 const char *data[] = {"data", "data"};
1288 err = hs_scan_vector(db, data, nullptr, 2, 0, scratch, dummy_cb, nullptr);
1289 ASSERT_NE(HS_SUCCESS, err);
1290 EXPECT_NE(HS_SCAN_TERMINATED, err);
1291
1292 // teardown
1293 err = hs_free_scratch(scratch);
1294 ASSERT_EQ(HS_SUCCESS, err);
1295 hs_free_database(db);
1296 }
1297
1298 // hs_scan_vector: Call with no scratch
TEST(HyperscanArgChecks,ScanVectorNoScratch)1299 TEST(HyperscanArgChecks, ScanVectorNoScratch) {
1300 hs_database_t *db = nullptr;
1301 hs_compile_error_t *compile_err = nullptr;
1302 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1303 &compile_err);
1304 ASSERT_EQ(HS_SUCCESS, err);
1305 ASSERT_TRUE(db != nullptr);
1306 const char *data[] = {"data", "data"};
1307 unsigned int len[] = {4, 4};
1308 err = hs_scan_vector(db, data, len, 2, 0, nullptr, dummy_cb, nullptr);
1309 ASSERT_NE(HS_SUCCESS, err);
1310 EXPECT_NE(HS_SCAN_TERMINATED, err);
1311
1312 // teardown
1313 hs_free_database(db);
1314 }
1315
1316 // hs_scan_vector: Call with no event handler
TEST(HyperscanArgChecks,ScanVectorNoHandler)1317 TEST(HyperscanArgChecks, ScanVectorNoHandler) {
1318 hs_database_t *db = nullptr;
1319 hs_compile_error_t *compile_err = nullptr;
1320 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1321 &compile_err);
1322 ASSERT_EQ(HS_SUCCESS, err);
1323 ASSERT_TRUE(db != nullptr);
1324 hs_scratch_t *scratch = nullptr;
1325 err = hs_alloc_scratch(db, &scratch);
1326 ASSERT_EQ(HS_SUCCESS, err);
1327 ASSERT_TRUE(scratch != nullptr);
1328 const char *data[] = {"data", "data"};
1329 unsigned int len[] = {4, 4};
1330 err = hs_scan_vector(db, data, len, 2, 0, scratch, nullptr, nullptr);
1331 ASSERT_EQ(HS_SUCCESS, err);
1332 EXPECT_NE(HS_SCAN_TERMINATED, err);
1333
1334 // teardown
1335 err = hs_free_scratch(scratch);
1336 ASSERT_EQ(HS_SUCCESS, err);
1337 hs_free_database(db);
1338 }
1339
1340 // hs_alloc_scratch: Call with no database
TEST(HyperscanArgChecks,AllocScratchNoDatabase)1341 TEST(HyperscanArgChecks, AllocScratchNoDatabase) {
1342 hs_scratch_t *scratch = nullptr;
1343 hs_error_t err = hs_alloc_scratch(nullptr, &scratch);
1344 EXPECT_NE(HS_SUCCESS, err);
1345 EXPECT_TRUE(scratch == nullptr);
1346 }
1347
1348 // hs_alloc_scratch: Call with NULL ptr-to-scratch
TEST(HyperscanArgChecks,AllocScratchNullScratchPtr)1349 TEST(HyperscanArgChecks, AllocScratchNullScratchPtr) {
1350 hs_database_t *db = nullptr;
1351 hs_compile_error_t *compile_err = nullptr;
1352 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1353 &compile_err);
1354 ASSERT_EQ(HS_SUCCESS, err);
1355 ASSERT_TRUE(db != nullptr);
1356
1357 err = hs_alloc_scratch(db, nullptr);
1358 ASSERT_EQ(HS_INVALID, err);
1359
1360 // teardown
1361 hs_free_database(db);
1362 }
1363
1364 // hs_alloc_scratch: Call with bogus scratch
TEST(HyperscanArgChecks,AllocScratchBogusScratch)1365 TEST(HyperscanArgChecks, AllocScratchBogusScratch) {
1366 hs_database_t *db = nullptr;
1367 hs_compile_error_t *compile_err = nullptr;
1368 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1369 &compile_err);
1370 ASSERT_EQ(HS_SUCCESS, err);
1371 ASSERT_TRUE(db != nullptr);
1372 hs_scratch_t *blah = (hs_scratch_t *)malloc(100);
1373 ASSERT_TRUE(blah != nullptr);
1374 memset(blah, 0xf0, 100);
1375 err = hs_alloc_scratch(db, &blah);
1376 ASSERT_EQ(HS_INVALID, err);
1377
1378 // teardown
1379 free(blah);
1380 hs_free_database(db);
1381 }
1382
1383 // hs_alloc_scratch: Call with broken database magic
TEST(HyperscanArgChecks,AllocScratchBadDatabaseMagic)1384 TEST(HyperscanArgChecks, AllocScratchBadDatabaseMagic) {
1385 hs_database_t *db = nullptr;
1386 hs_compile_error_t *compile_err = nullptr;
1387 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1388 &compile_err);
1389 ASSERT_EQ(HS_SUCCESS, err);
1390 ASSERT_TRUE(db != nullptr);
1391
1392 breakDatabaseMagic(db);
1393
1394 hs_scratch_t *scratch = nullptr;
1395 err = hs_alloc_scratch(db, &scratch);
1396 ASSERT_EQ(HS_INVALID, err);
1397
1398 // teardown
1399 free(db);
1400 }
1401
1402 // hs_alloc_scratch: Call with broken database version
TEST(HyperscanArgChecks,AllocScratchBadDatabaseVersion)1403 TEST(HyperscanArgChecks, AllocScratchBadDatabaseVersion) {
1404 hs_database_t *db = nullptr;
1405 hs_compile_error_t *compile_err = nullptr;
1406 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1407 &compile_err);
1408 ASSERT_EQ(HS_SUCCESS, err);
1409 ASSERT_TRUE(db != nullptr);
1410
1411 breakDatabaseVersion(db);
1412
1413 hs_scratch_t *scratch = nullptr;
1414 err = hs_alloc_scratch(db, &scratch);
1415 ASSERT_EQ(HS_DB_VERSION_ERROR, err);
1416
1417 // teardown
1418 hs_free_database(db);
1419 }
1420
1421 // hs_alloc_scratch: Call with broken database platform
TEST(HyperscanArgChecks,AllocScratchBadDatabasePlatform)1422 TEST(HyperscanArgChecks, AllocScratchBadDatabasePlatform) {
1423 hs_database_t *db = nullptr;
1424 hs_compile_error_t *compile_err = nullptr;
1425 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1426 &compile_err);
1427 ASSERT_EQ(HS_SUCCESS, err);
1428 ASSERT_TRUE(db != nullptr);
1429
1430 breakDatabasePlatform(db);
1431
1432 hs_scratch_t *scratch = nullptr;
1433 err = hs_alloc_scratch(db, &scratch);
1434 ASSERT_EQ(HS_DB_PLATFORM_ERROR, err);
1435
1436 // teardown
1437 hs_free_database(db);
1438 }
1439
1440 // hs_alloc_scratch: Call with broken database bytecode alignment
TEST(HyperscanArgChecks,AllocScratchBadDatabaseBytecode)1441 TEST(HyperscanArgChecks, AllocScratchBadDatabaseBytecode) {
1442 hs_database_t *db = nullptr;
1443 hs_compile_error_t *compile_err = nullptr;
1444 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1445 &compile_err);
1446 ASSERT_EQ(HS_SUCCESS, err);
1447 ASSERT_TRUE(db != nullptr);
1448
1449 breakDatabaseBytecode(db);
1450
1451 hs_scratch_t *scratch = nullptr;
1452 err = hs_alloc_scratch(db, &scratch);
1453 ASSERT_EQ(HS_INVALID, err);
1454
1455 // teardown
1456 hs_free_database(db);
1457 }
1458
1459 // hs_alloc_scratch: Call with broken database CRC
TEST(HyperscanArgChecks,AllocScratchBadDatabaseCRC)1460 TEST(HyperscanArgChecks, AllocScratchBadDatabaseCRC) {
1461 hs_database_t *db = nullptr;
1462 hs_compile_error_t *compile_err = nullptr;
1463 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1464 &compile_err);
1465 ASSERT_EQ(HS_SUCCESS, err);
1466 ASSERT_TRUE(db != nullptr);
1467
1468 size_t len = 0;
1469 err = hs_database_size(db, &len);
1470 ASSERT_EQ(HS_SUCCESS, err);
1471 ASSERT_NE(0U, len);
1472
1473 // ensure that we're able to alloc scratch for the unbroken db.
1474 hs_scratch_t *scratch = nullptr;
1475 err = hs_alloc_scratch(db, &scratch);
1476 ASSERT_EQ(HS_SUCCESS, err);
1477 err = hs_free_scratch(scratch);
1478 ASSERT_EQ(HS_SUCCESS, err);
1479
1480 // for want of a better case, corrupt the "middle byte" of the database.
1481 char *mid = (char *)db + len/2;
1482 *mid += 17;
1483
1484 scratch = nullptr;
1485 err = hs_alloc_scratch(db, &scratch);
1486 ASSERT_EQ(HS_INVALID, err);
1487
1488 // teardown
1489 hs_free_database(db);
1490 }
1491
1492 // hs_clone_scratch: Call with no source scratch
TEST(HyperscanArgChecks,CloneScratchNoSource)1493 TEST(HyperscanArgChecks, CloneScratchNoSource) {
1494 hs_scratch_t *scratch = nullptr, *scratch2 = nullptr;
1495 hs_error_t err = hs_clone_scratch(scratch, &scratch2);
1496 EXPECT_NE(HS_SUCCESS, err);
1497 EXPECT_TRUE(scratch2 == nullptr);
1498 }
1499
1500 // hs_serialize_database: Call with no database
TEST(HyperscanArgChecks,SerializeNoDatabase)1501 TEST(HyperscanArgChecks, SerializeNoDatabase) {
1502 char *bytes = nullptr;
1503 size_t length = 0;
1504 hs_error_t err = hs_serialize_database(nullptr, &bytes, &length);
1505 EXPECT_NE(HS_SUCCESS, err);
1506 EXPECT_TRUE(bytes == nullptr);
1507 }
1508
1509 // hs_serialize_database: Call with no bytes ptr
TEST(HyperscanArgChecks,SerializeNoBuffer)1510 TEST(HyperscanArgChecks, SerializeNoBuffer) {
1511 hs_database_t *db = nullptr;
1512 hs_compile_error_t *compile_err = nullptr;
1513 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1514 &compile_err);
1515 ASSERT_EQ(HS_SUCCESS, err);
1516 ASSERT_TRUE(db != nullptr);
1517
1518 size_t length = 0;
1519 err = hs_serialize_database(db, nullptr, &length);
1520 EXPECT_NE(HS_SUCCESS, err);
1521 EXPECT_EQ(0U, length);
1522
1523 // teardown
1524 hs_free_database(db);
1525 }
1526
1527 // hs_serialize_database: Call with no bytes ptr
TEST(HyperscanArgChecks,SerializeNoLength)1528 TEST(HyperscanArgChecks, SerializeNoLength) {
1529 hs_database_t *db = nullptr;
1530 hs_compile_error_t *compile_err = nullptr;
1531 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1532 &compile_err);
1533 ASSERT_EQ(HS_SUCCESS, err);
1534 ASSERT_TRUE(db != nullptr);
1535
1536 char *buf = nullptr;
1537 err = hs_serialize_database(db, &buf, nullptr);
1538 EXPECT_NE(HS_SUCCESS, err);
1539 EXPECT_TRUE(buf == nullptr);
1540
1541 // teardown
1542 hs_free_database(db);
1543 }
1544
1545 // hs_stream_size: Call with no database
TEST(HyperscanArgChecks,StreamSizeNoDatabase)1546 TEST(HyperscanArgChecks, StreamSizeNoDatabase) {
1547 size_t sz;
1548 hs_error_t err = hs_stream_size(nullptr, &sz);
1549 ASSERT_EQ(HS_INVALID, err);
1550 }
1551
1552 // hs_stream_size: Call with invalid database
TEST(HyperscanArgChecks,StreamSizeBogusDatabase)1553 TEST(HyperscanArgChecks, StreamSizeBogusDatabase) {
1554 hs_database_t *db = nullptr;
1555 hs_compile_error_t *compile_err = nullptr;
1556 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1557 &compile_err);
1558 ASSERT_EQ(HS_SUCCESS, err);
1559 ASSERT_TRUE(db != nullptr);
1560 size_t len;
1561 err = hs_database_size(db, &len);
1562 ASSERT_EQ(HS_SUCCESS, err);
1563 ASSERT_LT(0U, len);
1564
1565 memset(db, 0xf0, len);
1566
1567 size_t sz;
1568 err = hs_stream_size(db, &sz);
1569 ASSERT_EQ(HS_INVALID, err);
1570
1571 free(db);
1572 }
1573
1574 // hs_stream_size: Call with a block-mode database
TEST(HyperscanArgChecks,StreamSizeBlockDatabase)1575 TEST(HyperscanArgChecks, StreamSizeBlockDatabase) {
1576 hs_database_t *db = nullptr;
1577 hs_compile_error_t *compile_err = nullptr;
1578 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1579 &compile_err);
1580 ASSERT_EQ(HS_SUCCESS, err);
1581 ASSERT_TRUE(db != nullptr);
1582
1583 size_t sz;
1584 err = hs_stream_size(db, &sz);
1585 ASSERT_EQ(HS_DB_MODE_ERROR, err);
1586
1587 hs_free_database(db);
1588 }
1589
TEST(HyperscanArgChecks,StreamSizeVectoredDatabase)1590 TEST(HyperscanArgChecks, StreamSizeVectoredDatabase) {
1591 hs_database_t *db = nullptr;
1592 hs_compile_error_t *compile_err = nullptr;
1593 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1594 &compile_err);
1595 ASSERT_EQ(HS_SUCCESS, err);
1596 ASSERT_TRUE(db != nullptr);
1597
1598 size_t sz;
1599 err = hs_stream_size(db, &sz);
1600 ASSERT_EQ(HS_DB_MODE_ERROR, err);
1601
1602 hs_free_database(db);
1603 }
1604
TEST(HyperscanArgChecks,OpenStreamBlockDatabase)1605 TEST(HyperscanArgChecks, OpenStreamBlockDatabase) {
1606 hs_database_t *db = nullptr;
1607 hs_compile_error_t *compile_err = nullptr;
1608 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
1609 &compile_err);
1610 ASSERT_EQ(HS_SUCCESS, err);
1611 ASSERT_TRUE(db != nullptr);
1612
1613 hs_stream_t *id;
1614 err = hs_open_stream(db, 0, &id);
1615 ASSERT_EQ(HS_DB_MODE_ERROR, err);
1616
1617 hs_free_database(db);
1618 }
1619
TEST(HyperscanArgChecks,OpenStreamVectoredDatabase)1620 TEST(HyperscanArgChecks, OpenStreamVectoredDatabase) {
1621 hs_database_t *db = nullptr;
1622 hs_compile_error_t *compile_err = nullptr;
1623 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
1624 &compile_err);
1625 ASSERT_EQ(HS_SUCCESS, err);
1626 ASSERT_TRUE(db != nullptr);
1627
1628 hs_stream_t *id;
1629 err = hs_open_stream(db, 0, &id);
1630 ASSERT_EQ(HS_DB_MODE_ERROR, err);
1631
1632 hs_free_database(db);
1633 }
1634
1635
1636 // hs_stream_size: Call with a real database
TEST(HyperscanArgChecks,StreamSizeRealDatabase)1637 TEST(HyperscanArgChecks, StreamSizeRealDatabase) {
1638 hs_database_t *db = nullptr;
1639 hs_compile_error_t *compile_err = nullptr;
1640 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
1641 &compile_err);
1642 ASSERT_EQ(HS_SUCCESS, err);
1643 ASSERT_TRUE(db != nullptr);
1644
1645 size_t sz;
1646 err = hs_stream_size(db, &sz);
1647 ASSERT_EQ(HS_SUCCESS, err);
1648 ASSERT_NE(0U, sz)
1649 << "Stream-mode database should have non-zero stream size";
1650
1651 hs_free_database(db);
1652 }
1653
TEST(HyperscanArgChecks,StreamSizeNoSize)1654 TEST(HyperscanArgChecks, StreamSizeNoSize) {
1655 hs_database_t *db = nullptr;
1656 hs_compile_error_t *compile_err = nullptr;
1657 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
1658 &compile_err);
1659 ASSERT_EQ(HS_SUCCESS, err);
1660 ASSERT_TRUE(db != nullptr);
1661
1662 err = hs_stream_size(db, nullptr);
1663 ASSERT_EQ(HS_INVALID, err);
1664
1665 hs_free_database(db);
1666 }
1667
1668 // hs_database_size: Call with no database
TEST(HyperscanArgChecks,DatabaseSizeNoDatabase)1669 TEST(HyperscanArgChecks, DatabaseSizeNoDatabase) {
1670 size_t sz;
1671 hs_error_t err = hs_database_size(nullptr, &sz);
1672 ASSERT_EQ(HS_INVALID, err);
1673 }
1674
TEST(HyperscanArgChecks,DatabaseSizeNoSize)1675 TEST(HyperscanArgChecks, DatabaseSizeNoSize) {
1676 hs_database_t *db = nullptr;
1677 hs_compile_error_t *compile_err = nullptr;
1678 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
1679 &compile_err);
1680 ASSERT_EQ(HS_SUCCESS, err);
1681 ASSERT_TRUE(db != nullptr);
1682
1683 err = hs_database_size(db, nullptr);
1684 ASSERT_EQ(HS_INVALID, err);
1685
1686 hs_free_database(db);
1687 }
1688
TEST(HyperscanArgChecks,DatabaseSizeBadDb)1689 TEST(HyperscanArgChecks, DatabaseSizeBadDb) {
1690 hs_database_t *db = (hs_database_t *)garbage;
1691 size_t sz;
1692
1693 hs_error_t err = hs_database_size(db, &sz);
1694 ASSERT_EQ(HS_INVALID, err);
1695 }
1696
TEST(HyperscanArgChecks,DatabaseInfoBadDb)1697 TEST(HyperscanArgChecks, DatabaseInfoBadDb) {
1698 hs_database_t *db = (hs_database_t *)garbage;
1699 char *info = garbage;
1700 hs_error_t err = hs_database_info(db, &info);
1701 ASSERT_EQ(HS_INVALID, err);
1702 ASSERT_TRUE(nullptr == info);
1703 }
1704
TEST(HyperscanArgChecks,DatabaseInfoNullDb)1705 TEST(HyperscanArgChecks, DatabaseInfoNullDb) {
1706 char *info = garbage;
1707 hs_error_t err = hs_database_info(nullptr, &info);
1708 ASSERT_EQ(HS_INVALID, err);
1709 ASSERT_TRUE(nullptr == info);
1710 }
1711
TEST(HyperscanArgChecks,DatabaseInfoNullInfo)1712 TEST(HyperscanArgChecks, DatabaseInfoNullInfo) {
1713 hs_database_t *db;
1714 hs_compile_error_t *c_err;
1715 static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
1716
1717 hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
1718 ASSERT_EQ(HS_SUCCESS, err);
1719 ASSERT_TRUE(db != nullptr);
1720
1721 err = hs_database_info(db, nullptr);
1722 ASSERT_EQ(HS_INVALID, err);
1723
1724 hs_free_database(db);
1725 }
1726
TEST(HyperscanArgChecks,SerializedDatabaseSizeBadLen)1727 TEST(HyperscanArgChecks, SerializedDatabaseSizeBadLen) {
1728 hs_database_t *db;
1729 hs_compile_error_t *c_err;
1730 static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
1731
1732 hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
1733 ASSERT_EQ(HS_SUCCESS, err);
1734 ASSERT_TRUE(db != nullptr);
1735
1736 size_t db_len;
1737 err = hs_database_size(db, &db_len);
1738 ASSERT_EQ(HS_SUCCESS, err);
1739 ASSERT_NE(0, db_len);
1740
1741 char *bytes = nullptr;
1742 size_t bytes_len = 0;
1743
1744 err = hs_serialize_database(db, &bytes, &bytes_len);
1745 ASSERT_EQ(HS_SUCCESS, err);
1746 ASSERT_NE(0, bytes_len);
1747
1748 hs_free_database(db);
1749
1750 size_t ser_len;
1751 err = hs_serialized_database_size(bytes, 16, &ser_len);
1752 ASSERT_EQ(HS_INVALID, err);
1753
1754 free(bytes);
1755 }
1756
TEST(HyperscanArgChecks,SerializedDatabaseSizeNoSize)1757 TEST(HyperscanArgChecks, SerializedDatabaseSizeNoSize) {
1758 hs_database_t *db;
1759 hs_compile_error_t *c_err;
1760 static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
1761
1762 hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
1763 ASSERT_EQ(HS_SUCCESS, err);
1764 ASSERT_TRUE(db != nullptr);
1765
1766 size_t db_len;
1767 err = hs_database_size(db, &db_len);
1768 ASSERT_EQ(HS_SUCCESS, err);
1769 ASSERT_NE(0, db_len);
1770
1771 char *bytes = nullptr;
1772 size_t bytes_len = 0;
1773
1774 err = hs_serialize_database(db, &bytes, &bytes_len);
1775 ASSERT_EQ(HS_SUCCESS, err);
1776 ASSERT_NE(0, bytes_len);
1777
1778 hs_free_database(db);
1779
1780 err = hs_serialized_database_size(bytes, bytes_len, nullptr);
1781 ASSERT_EQ(HS_INVALID, err);
1782
1783 free(bytes);
1784 }
1785
TEST(HyperscanArgChecks,SerializedDatabaseSizeNoBytes)1786 TEST(HyperscanArgChecks, SerializedDatabaseSizeNoBytes) {
1787 size_t sz;
1788 hs_error_t err = hs_serialized_database_size(nullptr, 1024, &sz);
1789 ASSERT_EQ(HS_INVALID, err);
1790 }
1791
TEST(HyperscanArgChecks,SerializedDatabaseInfoBadLen)1792 TEST(HyperscanArgChecks, SerializedDatabaseInfoBadLen) {
1793 hs_database_t *db;
1794 hs_compile_error_t *c_err;
1795 static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
1796
1797 hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
1798 ASSERT_EQ(HS_SUCCESS, err);
1799 ASSERT_TRUE(db != nullptr);
1800
1801 size_t db_len;
1802 err = hs_database_size(db, &db_len);
1803 ASSERT_EQ(HS_SUCCESS, err);
1804 ASSERT_NE(0, db_len);
1805
1806 char *bytes = nullptr;
1807 size_t bytes_len = 0;
1808
1809 err = hs_serialize_database(db, &bytes, &bytes_len);
1810 ASSERT_EQ(HS_SUCCESS, err);
1811 ASSERT_NE(0, bytes_len);
1812
1813 hs_free_database(db);
1814
1815 char *info = garbage;
1816 err = hs_serialized_database_info(bytes, 16, &info);
1817 ASSERT_EQ(HS_INVALID, err);
1818 ASSERT_TRUE(nullptr == info);
1819
1820 free(bytes);
1821 }
1822
TEST(HyperscanArgChecks,SerializedDatabaseInfoNoInfo)1823 TEST(HyperscanArgChecks, SerializedDatabaseInfoNoInfo) {
1824 hs_database_t *db;
1825 hs_compile_error_t *c_err;
1826 static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
1827
1828 hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
1829 ASSERT_EQ(HS_SUCCESS, err);
1830 ASSERT_TRUE(db != nullptr);
1831
1832 size_t db_len;
1833 err = hs_database_size(db, &db_len);
1834 ASSERT_EQ(HS_SUCCESS, err);
1835 ASSERT_NE(0, db_len);
1836
1837 char *bytes = nullptr;
1838 size_t bytes_len = 0;
1839
1840 err = hs_serialize_database(db, &bytes, &bytes_len);
1841 ASSERT_EQ(HS_SUCCESS, err);
1842 ASSERT_NE(0, bytes_len);
1843
1844 hs_free_database(db);
1845
1846 err = hs_serialized_database_info(bytes, bytes_len, nullptr);
1847 ASSERT_EQ(HS_INVALID, err);
1848
1849 free(bytes);
1850 }
1851
TEST(HyperscanArgChecks,SerializedDatabaseInfoNoBytes)1852 TEST(HyperscanArgChecks, SerializedDatabaseInfoNoBytes) {
1853 char *info = garbage;
1854 hs_error_t err = hs_serialized_database_info(nullptr, 1024, &info);
1855 ASSERT_EQ(HS_INVALID, err);
1856 ASSERT_TRUE(nullptr == info);
1857 }
1858
TEST(HyperscanArgChecks,DeserializeDatabaseNoBytes)1859 TEST(HyperscanArgChecks, DeserializeDatabaseNoBytes) {
1860 hs_database_t *db = nullptr;
1861 hs_error_t err = hs_deserialize_database(nullptr, 2048, &db);
1862 ASSERT_EQ(HS_INVALID, err);
1863 }
1864
TEST(HyperscanArgChecks,DeserializeDatabaseAtNoBytes)1865 TEST(HyperscanArgChecks, DeserializeDatabaseAtNoBytes) {
1866 hs_database_t *db = nullptr;
1867 hs_error_t err = hs_deserialize_database_at(nullptr, 2048, db);
1868 ASSERT_EQ(HS_INVALID, err);
1869 }
1870
1871 static
makeSerializedDatabase(char ** bytes,size_t * length)1872 void makeSerializedDatabase(char **bytes, size_t *length) {
1873 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_BLOCK);
1874 ASSERT_NE(nullptr, db);
1875 hs_error_t err = hs_serialize_database(db, bytes, length);
1876 ASSERT_EQ(HS_SUCCESS, err);
1877 hs_free_database(db);
1878 }
1879
TEST(HyperscanArgChecks,DeserializeDatabaseNoDb)1880 TEST(HyperscanArgChecks, DeserializeDatabaseNoDb) {
1881 char *bytes = nullptr;
1882 size_t length = 0;
1883 makeSerializedDatabase(&bytes, &length);
1884 hs_error_t err = hs_deserialize_database(bytes, length, nullptr);
1885 ASSERT_EQ(HS_INVALID, err);
1886 free(bytes);
1887 }
1888
TEST(HyperscanArgChecks,DeserializeDatabaseBadLen)1889 TEST(HyperscanArgChecks, DeserializeDatabaseBadLen) {
1890 char *bytes = nullptr;
1891 size_t length = 0;
1892 makeSerializedDatabase(&bytes, &length);
1893 hs_database_t *db = nullptr;
1894 hs_error_t err = hs_deserialize_database(bytes, length - 1, &db);
1895 ASSERT_EQ(HS_INVALID, err);
1896 free(bytes);
1897 }
1898
TEST(HyperscanArgChecks,DeserializeDatabaseBadLen2)1899 TEST(HyperscanArgChecks, DeserializeDatabaseBadLen2) {
1900 char *bytes = nullptr;
1901 size_t length = 0;
1902 makeSerializedDatabase(&bytes, &length);
1903 hs_database_t *db = nullptr;
1904 hs_error_t err = hs_deserialize_database(bytes, length + 1, &db);
1905 ASSERT_EQ(HS_INVALID, err);
1906 free(bytes);
1907 }
1908
TEST(HyperscanArgChecks,DeserializeDatabaseBadBytes)1909 TEST(HyperscanArgChecks, DeserializeDatabaseBadBytes) {
1910 char *bytes = nullptr;
1911 size_t length = 0;
1912 makeSerializedDatabase(&bytes, &length);
1913 memset(bytes, 0xff, length); // scribble
1914 hs_database_t *db = nullptr;
1915 hs_error_t err = hs_deserialize_database(bytes, length, &db);
1916 ASSERT_EQ(HS_INVALID, err);
1917 free(bytes);
1918 }
1919
TEST(HyperscanArgChecks,DeserializeDatabaseBadBytes2)1920 TEST(HyperscanArgChecks, DeserializeDatabaseBadBytes2) {
1921 char *bytes = nullptr;
1922 size_t length = 0;
1923 makeSerializedDatabase(&bytes, &length);
1924 memset(bytes, 0, length); // scribble
1925 hs_database_t *db = nullptr;
1926 hs_error_t err = hs_deserialize_database(bytes, length, &db);
1927 ASSERT_EQ(HS_INVALID, err);
1928 free(bytes);
1929 }
1930
TEST(HyperscanArgChecks,DeserializeDatabaseAtNoDb)1931 TEST(HyperscanArgChecks, DeserializeDatabaseAtNoDb) {
1932 char *bytes = nullptr;
1933 size_t length = 0;
1934 makeSerializedDatabase(&bytes, &length);
1935 hs_error_t err = hs_deserialize_database_at(bytes, length, nullptr);
1936 ASSERT_EQ(HS_INVALID, err);
1937 free(bytes);
1938 }
1939
TEST(HyperscanArgChecks,DeserializeDatabaseAtBadLen)1940 TEST(HyperscanArgChecks, DeserializeDatabaseAtBadLen) {
1941 char *bytes = nullptr;
1942 size_t length = 0;
1943 makeSerializedDatabase(&bytes, &length);
1944 size_t db_length = 0;
1945 hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
1946 ASSERT_EQ(HS_SUCCESS, err);
1947 hs_database_t *db = (hs_database_t *)malloc(db_length);
1948 err = hs_deserialize_database_at(bytes, length - 1, db);
1949 ASSERT_EQ(HS_INVALID, err);
1950 free(bytes);
1951 free(db);
1952 }
1953
TEST(HyperscanArgChecks,DeserializeDatabaseAtBadLen2)1954 TEST(HyperscanArgChecks, DeserializeDatabaseAtBadLen2) {
1955 char *bytes = nullptr;
1956 size_t length = 0;
1957 makeSerializedDatabase(&bytes, &length);
1958 size_t db_length = 0;
1959 hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
1960 ASSERT_EQ(HS_SUCCESS, err);
1961 hs_database_t *db = (hs_database_t *)malloc(db_length);
1962 err = hs_deserialize_database_at(bytes, length + 1, db);
1963 ASSERT_EQ(HS_INVALID, err);
1964 free(bytes);
1965 free(db);
1966 }
1967
TEST(HyperscanArgChecks,DeserializeDatabaseAtBadBytes)1968 TEST(HyperscanArgChecks, DeserializeDatabaseAtBadBytes) {
1969 char *bytes = nullptr;
1970 size_t length = 0;
1971 makeSerializedDatabase(&bytes, &length);
1972 size_t db_length = 0;
1973 hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
1974 ASSERT_EQ(HS_SUCCESS, err);
1975 hs_database_t *db = (hs_database_t *)malloc(db_length);
1976 memset(bytes, 0xff, length); // scribble
1977 err = hs_deserialize_database_at(bytes, length, db);
1978 ASSERT_EQ(HS_INVALID, err);
1979 free(bytes);
1980 free(db);
1981 }
1982
TEST(HyperscanArgChecks,DeserializeDatabaseAtBadBytes2)1983 TEST(HyperscanArgChecks, DeserializeDatabaseAtBadBytes2) {
1984 char *bytes = nullptr;
1985 size_t length = 0;
1986 makeSerializedDatabase(&bytes, &length);
1987 size_t db_length = 0;
1988 hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
1989 ASSERT_EQ(HS_SUCCESS, err);
1990 hs_database_t *db = (hs_database_t *)malloc(db_length);
1991 memset(bytes, 0, length); // scribble
1992 err = hs_deserialize_database_at(bytes, length, db);
1993 ASSERT_EQ(HS_INVALID, err);
1994 free(bytes);
1995 free(db);
1996 }
1997
TEST(HyperscanArgChecks,ScratchSizeNoSize)1998 TEST(HyperscanArgChecks, ScratchSizeNoSize) {
1999 hs_error_t err;
2000
2001 // build a database
2002 hs_database_t *db = nullptr;
2003 hs_compile_error_t *compile_err = nullptr;
2004 err = hs_compile("foo.*bar$", 0, HS_MODE_STREAM, nullptr, &db, &compile_err);
2005 ASSERT_EQ(HS_SUCCESS, err);
2006
2007 // alloc some scratch
2008 hs_scratch_t *scratch = nullptr;
2009 err = hs_alloc_scratch(db, &scratch);
2010 ASSERT_EQ(HS_SUCCESS, err);
2011 EXPECT_TRUE(scratch != nullptr);
2012
2013 err = hs_scratch_size(scratch, nullptr);
2014 ASSERT_EQ(HS_INVALID, err);
2015
2016 err = hs_free_scratch(scratch);
2017 ASSERT_EQ(HS_SUCCESS, err);
2018 hs_free_database(db);
2019 }
2020
TEST(HyperscanArgChecks,ScratchSizeNoScratch)2021 TEST(HyperscanArgChecks, ScratchSizeNoScratch) {
2022 size_t size;
2023 hs_error_t err = hs_scratch_size(nullptr, &size);
2024 ASSERT_EQ(HS_INVALID, err);
2025 }
2026
TEST(HyperscanArgChecks,ScratchSizeBadScratch)2027 TEST(HyperscanArgChecks, ScratchSizeBadScratch) {
2028 hs_scratch_t *scratch = (hs_scratch_t *)garbage;
2029 size_t size;
2030 hs_error_t err = hs_scratch_size(scratch, &size);
2031 ASSERT_EQ(HS_INVALID, err);
2032 }
2033
2034 // hs_clone_scratch: bad scratch arg
TEST(HyperscanArgChecks,CloneBadScratch)2035 TEST(HyperscanArgChecks, CloneBadScratch) {
2036 // Try cloning the scratch
2037 void *local_garbage = malloc(sizeof(garbage));
2038 ASSERT_TRUE(local_garbage != nullptr);
2039 memcpy(local_garbage, garbage, sizeof(garbage));
2040 hs_scratch_t *cloned = nullptr;
2041 hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
2042 hs_error_t err = hs_clone_scratch(scratch, &cloned);
2043 free(local_garbage);
2044 ASSERT_EQ(HS_INVALID, err);
2045 }
2046
2047 // hs_scan: bad scratch arg
TEST(HyperscanArgChecks,ScanBadScratch)2048 TEST(HyperscanArgChecks, ScanBadScratch) {
2049 hs_database_t *db = nullptr;
2050 hs_compile_error_t *compile_err = nullptr;
2051 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
2052 &compile_err);
2053 ASSERT_EQ(HS_SUCCESS, err);
2054 ASSERT_TRUE(db != nullptr);
2055
2056 void *local_garbage = malloc(sizeof(garbage));
2057 ASSERT_TRUE(local_garbage != nullptr);
2058 memcpy(local_garbage, garbage, sizeof(garbage));
2059
2060 hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
2061 err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
2062 free(local_garbage);
2063 ASSERT_EQ(HS_INVALID, err);
2064
2065 // teardown
2066 hs_free_database(db);
2067 }
2068
2069 // hs_scan_stream: bad scratch arg
TEST(HyperscanArgChecks,ScanStreamBadScratch)2070 TEST(HyperscanArgChecks, ScanStreamBadScratch) {
2071 hs_database_t *db = nullptr;
2072 hs_compile_error_t *compile_err = nullptr;
2073 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
2074 &compile_err);
2075 ASSERT_EQ(HS_SUCCESS, err);
2076 ASSERT_TRUE(db != nullptr);
2077 void *local_garbage = malloc(sizeof(garbage));
2078 ASSERT_TRUE(local_garbage != nullptr);
2079 memcpy(local_garbage, garbage, sizeof(garbage));
2080 hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
2081
2082 hs_stream_t *stream = nullptr;
2083 err = hs_open_stream(db, 0, &stream);
2084 ASSERT_EQ(HS_SUCCESS, err);
2085 ASSERT_TRUE(stream != nullptr);
2086
2087 err = hs_scan_stream(stream, "data", 4, 0, scratch, nullptr, nullptr);
2088 EXPECT_NE(HS_SUCCESS, err);
2089 EXPECT_NE(HS_SCAN_TERMINATED, err);
2090
2091 // teardown
2092 err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
2093 EXPECT_EQ(HS_INVALID, err);
2094 scratch = nullptr;
2095 err = hs_alloc_scratch(db, &scratch);
2096 ASSERT_EQ(HS_SUCCESS, err);
2097 ASSERT_TRUE(scratch != nullptr);
2098 hs_close_stream(stream, scratch, nullptr, nullptr);
2099 hs_free_database(db);
2100 err = hs_free_scratch(scratch);
2101 ASSERT_EQ(HS_SUCCESS, err);
2102 free(local_garbage);
2103 }
2104
2105 // hs_reset_stream: bad scratch arg
TEST(HyperscanArgChecks,ResetStreamBadScratch)2106 TEST(HyperscanArgChecks, ResetStreamBadScratch) {
2107 hs_database_t *db = nullptr;
2108 hs_compile_error_t *compile_err = nullptr;
2109 hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
2110 &compile_err);
2111 ASSERT_EQ(HS_SUCCESS, err);
2112 ASSERT_TRUE(db != nullptr);
2113 void *local_garbage = malloc(sizeof(garbage));
2114 ASSERT_TRUE(local_garbage != nullptr);
2115 memcpy(local_garbage, garbage, sizeof(garbage));
2116 hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
2117
2118 hs_stream_t *stream = nullptr;
2119 err = hs_open_stream(db, 0, &stream);
2120 ASSERT_EQ(HS_SUCCESS, err);
2121 ASSERT_TRUE(stream != nullptr);
2122
2123 err = hs_reset_stream(stream, 0, scratch, dummy_cb, nullptr);
2124 EXPECT_NE(HS_SUCCESS, err);
2125 EXPECT_NE(HS_SCAN_TERMINATED, err);
2126
2127 // teardown
2128 err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
2129 EXPECT_EQ(HS_INVALID, err);
2130 scratch = nullptr;
2131 err = hs_alloc_scratch(db, &scratch);
2132 ASSERT_EQ(HS_SUCCESS, err);
2133 ASSERT_TRUE(scratch != nullptr);
2134 hs_close_stream(stream, scratch, nullptr, nullptr);
2135 hs_free_database(db);
2136 err = hs_free_scratch(scratch);
2137 ASSERT_EQ(HS_SUCCESS, err);
2138 free(local_garbage);
2139 }
2140
2141 // hs_scan_stream: bad scratch arg
TEST(HyperscanArgChecks,ScanVectorBadScratch)2142 TEST(HyperscanArgChecks, ScanVectorBadScratch) {
2143 hs_database_t *db = nullptr;
2144 hs_compile_error_t *compile_err = nullptr;
2145 hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
2146 &compile_err);
2147 ASSERT_EQ(HS_SUCCESS, err);
2148 ASSERT_TRUE(db != nullptr);
2149 void *local_garbage = malloc(sizeof(garbage));
2150 ASSERT_TRUE(local_garbage != nullptr);
2151 memcpy(local_garbage, garbage, sizeof(garbage));
2152 hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
2153
2154 const char *data[] = { "data" };
2155 unsigned int len[] = { 4 };
2156
2157 err = hs_scan_vector(db, data, len, 1, 0, scratch, dummy_cb, nullptr);
2158
2159 EXPECT_NE(HS_SUCCESS, err);
2160 EXPECT_NE(HS_SCAN_TERMINATED, err);
2161
2162 // teardown
2163 hs_free_database(db);
2164 free(local_garbage);
2165 }
2166
2167 // hs_scan: bad (freed) scratch arg
2168 // disabled as, unsurprisingly, valgrind complains
2169 #ifdef TEST_FREED_MEM
TEST(HyperscanArgChecks,ScanFreedScratch)2170 TEST(HyperscanArgChecks, ScanFreedScratch) {
2171 hs_database_t *db = 0;
2172 hs_compile_error_t *compile_err = 0;
2173 hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, NULL, &db,
2174 &compile_err);
2175 ASSERT_EQ(HS_SUCCESS, err);
2176 ASSERT_TRUE(db != NULL);
2177 hs_scratch_t *scratch = 0;
2178 err = hs_alloc_scratch(db, &scratch);
2179 ASSERT_EQ(HS_SUCCESS, err);
2180 ASSERT_TRUE(scratch != NULL);
2181 err = hs_free_scratch(scratch);
2182 ASSERT_EQ(HS_SUCCESS, err);
2183 err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, 0);
2184 ASSERT_EQ(HS_INVALID, err);
2185 EXPECT_NE(HS_SCAN_TERMINATED, err);
2186
2187 // teardown
2188 hs_free_database(db);
2189 }
2190 #endif // TEST_FREED_MEM
2191
2192 // hs_expression_info: Compile a NULL pattern
TEST(HyperscanArgChecks,ExprInfoNullExpression)2193 TEST(HyperscanArgChecks, ExprInfoNullExpression) {
2194 hs_expr_info_t *info = nullptr;
2195 hs_compile_error_t *compile_err = nullptr;
2196 hs_error_t err = hs_expression_info(nullptr, 0, &info, &compile_err);
2197 EXPECT_EQ(HS_COMPILER_ERROR, err);
2198 EXPECT_TRUE(info == nullptr);
2199 EXPECT_TRUE(compile_err != nullptr);
2200 hs_free_compile_error(compile_err);
2201 }
2202
2203 // hs_expression_info: NULL info block ptr
TEST(HyperscanArgChecks,ExprInfoNullInfoPtr)2204 TEST(HyperscanArgChecks, ExprInfoNullInfoPtr) {
2205 hs_compile_error_t *compile_err = nullptr;
2206 hs_error_t err = hs_expression_info("foobar", 0, nullptr, &compile_err);
2207 EXPECT_EQ(HS_COMPILER_ERROR, err);
2208 EXPECT_TRUE(compile_err != nullptr);
2209 hs_free_compile_error(compile_err);
2210 }
2211
2212 // hs_expression_info: No compiler error block
TEST(HyperscanArgChecks,ExprInfoNullErrPtr)2213 TEST(HyperscanArgChecks, ExprInfoNullErrPtr) {
2214 hs_expr_info_t *info = nullptr;
2215 hs_error_t err = hs_expression_info("foobar", 0, &info, nullptr);
2216 EXPECT_EQ(HS_COMPILER_ERROR, err);
2217 EXPECT_TRUE(info == nullptr);
2218 }
2219
2220 // hs_expression_ext_info: Compile a NULL pattern
TEST(HyperscanArgChecks,ExprExtInfoNullExpression)2221 TEST(HyperscanArgChecks, ExprExtInfoNullExpression) {
2222 hs_expr_info_t *info = nullptr;
2223 hs_compile_error_t *compile_err = nullptr;
2224 hs_error_t err =
2225 hs_expression_ext_info(nullptr, 0, nullptr, &info, &compile_err);
2226 EXPECT_EQ(HS_COMPILER_ERROR, err);
2227 EXPECT_TRUE(info == nullptr);
2228 EXPECT_TRUE(compile_err != nullptr);
2229 hs_free_compile_error(compile_err);
2230 }
2231
2232 // hs_expression_ext_info: NULL info block ptr
TEST(HyperscanArgChecks,ExprExtInfoNullInfoPtr)2233 TEST(HyperscanArgChecks, ExprExtInfoNullInfoPtr) {
2234 hs_compile_error_t *compile_err = nullptr;
2235 hs_error_t err =
2236 hs_expression_ext_info("foobar", 0, nullptr, nullptr, &compile_err);
2237 EXPECT_EQ(HS_COMPILER_ERROR, err);
2238 EXPECT_TRUE(compile_err != nullptr);
2239 hs_free_compile_error(compile_err);
2240 }
2241
2242 // hs_expression_ext_info: No compiler error block
TEST(HyperscanArgChecks,ExprExtInfoNullErrPtr)2243 TEST(HyperscanArgChecks, ExprExtInfoNullErrPtr) {
2244 hs_expr_info_t *info = nullptr;
2245 hs_error_t err =
2246 hs_expression_ext_info("foobar", 0, nullptr, &info, nullptr);
2247 EXPECT_EQ(HS_COMPILER_ERROR, err);
2248 EXPECT_TRUE(info == nullptr);
2249 }
2250
TEST(HyperscanArgChecks,hs_free_database_null)2251 TEST(HyperscanArgChecks, hs_free_database_null) {
2252 hs_error_t err = hs_free_database(nullptr);
2253 ASSERT_EQ(HS_SUCCESS, err);
2254 }
2255
TEST(HyperscanArgChecks,hs_free_database_garbage)2256 TEST(HyperscanArgChecks, hs_free_database_garbage) {
2257 hs_error_t err = hs_free_database((hs_database_t *)garbage);
2258 ASSERT_EQ(HS_INVALID, err);
2259 }
2260
TEST(HyperscanArgChecks,hs_free_scratch_null)2261 TEST(HyperscanArgChecks, hs_free_scratch_null) {
2262 hs_error_t err = hs_free_scratch(nullptr);
2263 ASSERT_EQ(HS_SUCCESS, err);
2264 }
2265
TEST(HyperscanArgChecks,hs_free_scratch_garbage)2266 TEST(HyperscanArgChecks, hs_free_scratch_garbage) {
2267 hs_error_t err = hs_free_scratch((hs_scratch_t *)garbage);
2268 ASSERT_EQ(HS_INVALID, err);
2269 }
2270
TEST(HyperscanArgChecks,hs_free_compile_error_null)2271 TEST(HyperscanArgChecks, hs_free_compile_error_null) {
2272 hs_error_t err = hs_free_compile_error(nullptr);
2273 ASSERT_EQ(HS_SUCCESS, err);
2274 }
2275
TEST(HyperscanArgChecks,multicompile_mix_highlander_1)2276 TEST(HyperscanArgChecks, multicompile_mix_highlander_1) {
2277 hs_database_t *db = nullptr;
2278 hs_compile_error_t *compile_err = nullptr;
2279 const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
2280 unsigned flags[] = {HS_FLAG_SINGLEMATCH, 0};
2281 unsigned ids[] = {30, 30};
2282 hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
2283 nullptr, &db, &compile_err);
2284 ASSERT_EQ(HS_COMPILER_ERROR, err);
2285 hs_free_compile_error(compile_err);
2286 }
2287
TEST(HyperscanArgChecks,multicompile_mix_highlander_2)2288 TEST(HyperscanArgChecks, multicompile_mix_highlander_2) {
2289 hs_database_t *db = nullptr;
2290 hs_compile_error_t *compile_err = nullptr;
2291 const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
2292 unsigned flags[] = {0, HS_FLAG_SINGLEMATCH};
2293 unsigned ids[] = {30, 30};
2294 hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
2295 nullptr, &db, &compile_err);
2296 ASSERT_EQ(HS_COMPILER_ERROR, err);
2297 hs_free_compile_error(compile_err);
2298 }
2299
TEST(HyperscanArgChecks,multicompile_nomix_highlander_1)2300 TEST(HyperscanArgChecks, multicompile_nomix_highlander_1) {
2301 hs_database_t *db = nullptr;
2302 hs_compile_error_t *compile_err = nullptr;
2303 const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
2304 unsigned flags[] = {HS_FLAG_SINGLEMATCH, HS_FLAG_SINGLEMATCH};
2305 unsigned ids[] = {30, 30};
2306 hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
2307 nullptr, &db, &compile_err);
2308 ASSERT_EQ(HS_SUCCESS, err);
2309 hs_free_database(db);
2310 }
2311
TEST(HyperscanArgChecks,multicompile_nomix_highlander_2)2312 TEST(HyperscanArgChecks, multicompile_nomix_highlander_2) {
2313 hs_database_t *db = nullptr;
2314 hs_compile_error_t *compile_err = nullptr;
2315 const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
2316 unsigned flags[] = {0, 0};
2317 unsigned ids[] = {30, 30};
2318 hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
2319 nullptr, &db, &compile_err);
2320 ASSERT_EQ(HS_SUCCESS, err);
2321 hs_free_database(db);
2322 }
2323
TEST(HyperscanArgChecks,hs_populate_platform_null)2324 TEST(HyperscanArgChecks, hs_populate_platform_null) {
2325 hs_error_t err = hs_populate_platform(nullptr);
2326 ASSERT_EQ(HS_INVALID, err);
2327 }
2328
TEST(HyperscanArgChecks,CompressStreamNoStream)2329 TEST(HyperscanArgChecks, CompressStreamNoStream) {
2330 char buf[100];
2331 size_t used;
2332 hs_error_t err = hs_compress_stream(nullptr, buf, sizeof(buf), &used);
2333 ASSERT_EQ(HS_INVALID, err);
2334 }
2335
TEST(HyperscanArgChecks,CompressStreamNoUsed)2336 TEST(HyperscanArgChecks, CompressStreamNoUsed) {
2337 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2338 ASSERT_NE(nullptr, db);
2339
2340 hs_stream_t *stream;
2341 hs_error_t err = hs_open_stream(db, 0, &stream);
2342 ASSERT_EQ(HS_SUCCESS, err);
2343
2344 char buf[100];
2345 err = hs_compress_stream(stream, buf, sizeof(buf), nullptr);
2346 ASSERT_EQ(HS_INVALID, err);
2347
2348 err = hs_close_stream(stream, nullptr, nullptr, nullptr);
2349 ASSERT_EQ(HS_SUCCESS, err);
2350
2351 err = hs_free_database(db);
2352 ASSERT_EQ(HS_SUCCESS, err);
2353 }
2354
TEST(HyperscanArgChecks,CompressStreamNoBuf)2355 TEST(HyperscanArgChecks, CompressStreamNoBuf) {
2356 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2357 ASSERT_NE(nullptr, db);
2358
2359 hs_stream_t *stream;
2360 hs_error_t err = hs_open_stream(db, 0, &stream);
2361 ASSERT_EQ(HS_SUCCESS, err);
2362
2363 char buf[100];
2364 size_t used;
2365 err = hs_compress_stream(stream, nullptr, sizeof(buf), &used);
2366 ASSERT_EQ(HS_INVALID, err);
2367
2368 err = hs_close_stream(stream, nullptr, nullptr, nullptr);
2369 ASSERT_EQ(HS_SUCCESS, err);
2370
2371 err = hs_free_database(db);
2372 ASSERT_EQ(HS_SUCCESS, err);
2373 }
2374
TEST(HyperscanArgChecks,CompressStreamSmallBuff)2375 TEST(HyperscanArgChecks, CompressStreamSmallBuff) {
2376 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2377 ASSERT_NE(nullptr, db);
2378
2379 hs_stream_t *stream;
2380 hs_error_t err = hs_open_stream(db, 0, &stream);
2381 ASSERT_EQ(HS_SUCCESS, err);
2382
2383 char buf[100];
2384 size_t used = 0;
2385 err = hs_compress_stream(stream, buf, 1, &used);
2386 ASSERT_EQ(HS_INSUFFICIENT_SPACE, err);
2387 ASSERT_LT(0, used);
2388
2389 err = hs_close_stream(stream, nullptr, nullptr, nullptr);
2390 ASSERT_EQ(HS_SUCCESS, err);
2391
2392 err = hs_free_database(db);
2393 ASSERT_EQ(HS_SUCCESS, err);
2394 }
2395
TEST(HyperscanArgChecks,ExpandNoDb)2396 TEST(HyperscanArgChecks, ExpandNoDb) {
2397 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2398 ASSERT_NE(nullptr, db);
2399
2400 hs_stream_t *stream1;
2401 hs_error_t err = hs_open_stream(db, 0, &stream1);
2402 ASSERT_EQ(HS_SUCCESS, err);
2403
2404 char buf[2000];
2405 size_t used = 0;
2406 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2407 ASSERT_EQ(HS_SUCCESS, err);
2408
2409 hs_stream_t *stream2;
2410 err = hs_expand_stream(nullptr, &stream2, buf, used);
2411 ASSERT_EQ(HS_INVALID, err);
2412
2413 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2414 ASSERT_EQ(HS_SUCCESS, err);
2415
2416 err = hs_free_database(db);
2417 ASSERT_EQ(HS_SUCCESS, err);
2418 }
2419
TEST(HyperscanArgChecks,ExpandNoTo)2420 TEST(HyperscanArgChecks, ExpandNoTo) {
2421 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2422 ASSERT_NE(nullptr, db);
2423
2424 hs_stream_t *stream1;
2425 hs_error_t err = hs_open_stream(db, 0, &stream1);
2426 ASSERT_EQ(HS_SUCCESS, err);
2427
2428 char buf[2000];
2429 size_t used = 0;
2430 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2431 ASSERT_EQ(HS_SUCCESS, err);
2432
2433 hs_stream_t *stream2;
2434 err = hs_expand_stream(db, nullptr, buf, used);
2435 ASSERT_EQ(HS_INVALID, err);
2436
2437 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2438 ASSERT_EQ(HS_SUCCESS, err);
2439
2440 err = hs_free_database(db);
2441 ASSERT_EQ(HS_SUCCESS, err);
2442 }
2443
TEST(HyperscanArgChecks,ExpandNoBuf)2444 TEST(HyperscanArgChecks, ExpandNoBuf) {
2445 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2446 ASSERT_NE(nullptr, db);
2447
2448 hs_stream_t *stream1;
2449 hs_error_t err = hs_open_stream(db, 0, &stream1);
2450 ASSERT_EQ(HS_SUCCESS, err);
2451
2452 char buf[2000];
2453 size_t used = 0;
2454 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2455 ASSERT_EQ(HS_SUCCESS, err);
2456
2457 hs_stream_t *stream2;
2458 err = hs_expand_stream(db, &stream2, nullptr, used);
2459 ASSERT_EQ(HS_INVALID, err);
2460
2461 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2462 ASSERT_EQ(HS_SUCCESS, err);
2463
2464 err = hs_free_database(db);
2465 ASSERT_EQ(HS_SUCCESS, err);
2466 }
2467
TEST(HyperscanArgChecks,ExpandSmallBuf)2468 TEST(HyperscanArgChecks, ExpandSmallBuf) {
2469 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2470 ASSERT_NE(nullptr, db);
2471
2472 hs_stream_t *stream1;
2473 hs_error_t err = hs_open_stream(db, 0, &stream1);
2474 ASSERT_EQ(HS_SUCCESS, err);
2475
2476 char buf[2000];
2477 size_t used = 0;
2478 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2479 ASSERT_EQ(HS_SUCCESS, err);
2480
2481 hs_stream_t *stream2;
2482 err = hs_expand_stream(db, &stream2, buf, used / 2);
2483 ASSERT_EQ(HS_INVALID, err);
2484
2485 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2486 ASSERT_EQ(HS_SUCCESS, err);
2487
2488 err = hs_free_database(db);
2489 ASSERT_EQ(HS_SUCCESS, err);
2490 }
2491
TEST(HyperscanArgChecks,ResetAndExpandNoStream)2492 TEST(HyperscanArgChecks, ResetAndExpandNoStream) {
2493 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2494 ASSERT_NE(nullptr, db);
2495
2496 hs_stream_t *stream1;
2497 hs_error_t err = hs_open_stream(db, 0, &stream1);
2498 ASSERT_EQ(HS_SUCCESS, err);
2499
2500 char buf[2000];
2501 size_t used = 0;
2502 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2503 ASSERT_EQ(HS_SUCCESS, err);
2504
2505 err = hs_reset_and_expand_stream(nullptr, buf, used, nullptr, nullptr,
2506 nullptr);
2507 ASSERT_EQ(HS_INVALID, err);
2508
2509 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2510 ASSERT_EQ(HS_SUCCESS, err);
2511
2512 err = hs_free_database(db);
2513 ASSERT_EQ(HS_SUCCESS, err);
2514 }
2515
TEST(HyperscanArgChecks,ResetAndExpandNoBuf)2516 TEST(HyperscanArgChecks, ResetAndExpandNoBuf) {
2517 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2518 ASSERT_NE(nullptr, db);
2519
2520 hs_stream_t *stream1;
2521 hs_error_t err = hs_open_stream(db, 0, &stream1);
2522 ASSERT_EQ(HS_SUCCESS, err);
2523
2524 char buf[2000];
2525 size_t used = 0;
2526 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2527 ASSERT_EQ(HS_SUCCESS, err);
2528
2529 hs_stream_t *stream2;
2530 err = hs_open_stream(db, 0, &stream2);
2531 ASSERT_EQ(HS_SUCCESS, err);
2532
2533 err = hs_reset_and_expand_stream(stream2, nullptr, used, nullptr, nullptr,
2534 nullptr);
2535 ASSERT_EQ(HS_INVALID, err);
2536
2537 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2538 ASSERT_EQ(HS_SUCCESS, err);
2539
2540 err = hs_close_stream(stream2, nullptr, nullptr, nullptr);
2541 ASSERT_EQ(HS_SUCCESS, err);
2542
2543 err = hs_free_database(db);
2544 ASSERT_EQ(HS_SUCCESS, err);
2545 }
2546
2547
TEST(HyperscanArgChecks,ResetAndExpandSmallBuf)2548 TEST(HyperscanArgChecks, ResetAndExpandSmallBuf) {
2549 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2550 ASSERT_NE(nullptr, db);
2551
2552 hs_stream_t *stream1;
2553 hs_error_t err = hs_open_stream(db, 0, &stream1);
2554 ASSERT_EQ(HS_SUCCESS, err);
2555
2556 char buf[2000];
2557 size_t used = 0;
2558 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2559 ASSERT_EQ(HS_SUCCESS, err);
2560
2561 hs_stream_t *stream2;
2562 err = hs_open_stream(db, 0, &stream2);
2563 ASSERT_EQ(HS_SUCCESS, err);
2564
2565 err = hs_reset_and_expand_stream(stream2, buf, used / 2, nullptr, nullptr,
2566 nullptr);
2567 ASSERT_EQ(HS_INVALID, err);
2568
2569 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2570 ASSERT_EQ(HS_SUCCESS, err);
2571
2572 err = hs_close_stream(stream2, nullptr, nullptr, nullptr);
2573 ASSERT_EQ(HS_SUCCESS, err);
2574
2575 err = hs_free_database(db);
2576 ASSERT_EQ(HS_SUCCESS, err);
2577 }
2578
TEST(HyperscanArgChecks,ResetAndExpandNoScratch)2579 TEST(HyperscanArgChecks, ResetAndExpandNoScratch) {
2580 hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
2581 ASSERT_NE(nullptr, db);
2582
2583 hs_stream_t *stream1;
2584 hs_error_t err = hs_open_stream(db, 0, &stream1);
2585 ASSERT_EQ(HS_SUCCESS, err);
2586
2587 char buf[2000];
2588 size_t used = 0;
2589 err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
2590 ASSERT_EQ(HS_SUCCESS, err);
2591
2592 hs_stream_t *stream2;
2593 err = hs_open_stream(db, 0, &stream2);
2594 ASSERT_EQ(HS_SUCCESS, err);
2595
2596 int temp;
2597
2598 err = hs_reset_and_expand_stream(stream2, buf, used, nullptr, singleHandler,
2599 &temp);
2600 ASSERT_EQ(HS_INVALID, err);
2601
2602 err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
2603 ASSERT_EQ(HS_SUCCESS, err);
2604
2605 err = hs_close_stream(stream2, nullptr, nullptr, nullptr);
2606 ASSERT_EQ(HS_SUCCESS, err);
2607
2608 err = hs_free_database(db);
2609 ASSERT_EQ(HS_SUCCESS, err);
2610 }
2611
2612 class BadModeTest : public testing::TestWithParam<unsigned> {};
2613
2614 // hs_compile: Compile a pattern with bogus mode flags set.
TEST_P(BadModeTest,FailCompile)2615 TEST_P(BadModeTest, FailCompile) {
2616 hs_database_t *db = nullptr;
2617 hs_compile_error_t *compile_err = nullptr;
2618
2619 unsigned mode = GetParam();
2620 SCOPED_TRACE(mode);
2621
2622 hs_error_t err = hs_compile("foo", 0, mode, nullptr, &db, &compile_err);
2623 ASSERT_EQ(HS_COMPILER_ERROR, err);
2624 ASSERT_TRUE(compile_err != nullptr);
2625 ASSERT_TRUE(compile_err->message != nullptr);
2626 hs_free_compile_error(compile_err);
2627 }
2628
2629 static const unsigned badModeValues[] = {
2630 // Multiple modes at once.
2631 HS_MODE_BLOCK | HS_MODE_STREAM | HS_MODE_VECTORED,
2632 HS_MODE_BLOCK | HS_MODE_STREAM,
2633 HS_MODE_BLOCK | HS_MODE_VECTORED,
2634 HS_MODE_STREAM | HS_MODE_VECTORED,
2635 // SOM horizon modes are only accepted in streaming mode.
2636 HS_MODE_BLOCK | HS_MODE_SOM_HORIZON_LARGE,
2637 HS_MODE_BLOCK | HS_MODE_SOM_HORIZON_MEDIUM,
2638 HS_MODE_BLOCK | HS_MODE_SOM_HORIZON_SMALL,
2639 HS_MODE_VECTORED | HS_MODE_SOM_HORIZON_LARGE,
2640 HS_MODE_VECTORED | HS_MODE_SOM_HORIZON_MEDIUM,
2641 HS_MODE_VECTORED | HS_MODE_SOM_HORIZON_SMALL,
2642 // Can't specify more than one SOM horizon.
2643 HS_MODE_STREAM | HS_MODE_SOM_HORIZON_LARGE | HS_MODE_SOM_HORIZON_MEDIUM | HS_MODE_SOM_HORIZON_SMALL,
2644 HS_MODE_STREAM | HS_MODE_SOM_HORIZON_LARGE | HS_MODE_SOM_HORIZON_SMALL,
2645 HS_MODE_STREAM | HS_MODE_SOM_HORIZON_LARGE | HS_MODE_SOM_HORIZON_MEDIUM,
2646 HS_MODE_STREAM | HS_MODE_SOM_HORIZON_MEDIUM | HS_MODE_SOM_HORIZON_SMALL,
2647 };
2648
2649 INSTANTIATE_TEST_CASE_P(HyperscanArgChecks, BadModeTest,
2650 testing::ValuesIn(badModeValues));
2651
2652 } // namespace
2653
2654