mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
2654 lines
86 KiB
C++
2654 lines
86 KiB
C++
/*
|
|
* Copyright (c) 2015-2017, Intel Corporation
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of Intel Corporation nor the names of its contributors
|
|
* may be used to endorse or promote products derived from this software
|
|
* without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "gtest/gtest.h"
|
|
#include "hs.h"
|
|
#include "test_util.h"
|
|
|
|
static char garbage[] = "TEST(HyperscanArgChecks, DatabaseSizeNoDatabase) {" \
|
|
" size_t sz = hs_database_size(0);" \
|
|
" ASSERT_EQ(0, sz);";
|
|
|
|
static unsigned lastMatchId = 0;
|
|
static unsigned long long lastMatchFrom = 0;
|
|
static unsigned long long lastMatchTo = 0;
|
|
static unsigned lastMatchFlags = 0;
|
|
static void *lastMatchCtx = nullptr;
|
|
|
|
// Single match callback: record all the details from a single match
|
|
static
|
|
int singleHandler(unsigned id, unsigned long long from,
|
|
unsigned long long to, unsigned flags, void *ctx) {
|
|
lastMatchId = id;
|
|
lastMatchFrom = from;
|
|
lastMatchTo = to;
|
|
lastMatchFlags = flags;
|
|
lastMatchCtx = ctx;
|
|
return 0;
|
|
}
|
|
|
|
namespace /* anonymous */ {
|
|
|
|
// Break the magic number of the given database.
|
|
void breakDatabaseMagic(hs_database *db) {
|
|
// database magic should be 0xdbdb at the start
|
|
ASSERT_TRUE(memcmp("\xdb\xdb", db, 2) == 0);
|
|
*(char *)db = 0xdc;
|
|
}
|
|
|
|
// Break the version number of the given database.
|
|
void breakDatabaseVersion(hs_database *db) {
|
|
// database version is the second u32
|
|
*((char *)db + 4) += 1;
|
|
}
|
|
|
|
// Break the platform data of the given database.
|
|
void breakDatabasePlatform(hs_database *db) {
|
|
// database platform is an aligned u64a 16 bytes in
|
|
memset((char *)db + 16, 0xff, 8);
|
|
}
|
|
|
|
// Break the alignment of the bytecode for the given database.
|
|
void breakDatabaseBytecode(hs_database *db) {
|
|
// bytecode ptr is a u32, 36 bytes in
|
|
unsigned int *bytecode = (unsigned int *)((char *)db + 36);
|
|
ASSERT_NE(0U, *bytecode);
|
|
ASSERT_EQ(0U, (size_t)((char *)db + *bytecode) % 16U);
|
|
*bytecode += 3;
|
|
}
|
|
|
|
// Check that hs_valid_platform says we can run here
|
|
TEST(HyperscanArgChecks, ValidPlatform) {
|
|
hs_error_t error = hs_valid_platform();
|
|
ASSERT_EQ(HS_SUCCESS, error) << "hs_valid_platform should return zero";
|
|
}
|
|
|
|
// Check that hs_version gives us a reasonable string back
|
|
TEST(HyperscanArgChecks, Version) {
|
|
const char *version = hs_version();
|
|
ASSERT_TRUE(version != nullptr);
|
|
ASSERT_TRUE(version[0] >= '0' && version[0] <= '9') << "First byte should be a digit.";
|
|
ASSERT_EQ('.', version[1]) << "Second byte should be a dot.";
|
|
}
|
|
|
|
// hs_compile: Compile a NULL pattern (block mode)
|
|
TEST(HyperscanArgChecks, SingleCompileBlockNoPattern) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile(nullptr, 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(db == nullptr);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Compile a NULL pattern (streaming mode)
|
|
TEST(HyperscanArgChecks, SingleCompileStreamingNoPattern) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile(nullptr, 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(db == nullptr);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Compile a pattern to a NULL database ptr (block mode)
|
|
TEST(HyperscanArgChecks, SingleCompileBlockNoDatabase) {
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, nullptr,
|
|
&compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Compile a pattern to a NULL database ptr (streaming mode)
|
|
TEST(HyperscanArgChecks, SingleCompileStreamingNoDatabase) {
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, nullptr,
|
|
&compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Compile a pattern with no mode set
|
|
TEST(HyperscanArgChecks, SingleCompileNoMode) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, 0, nullptr, &db, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Compile a pattern with several modes set
|
|
TEST(HyperscanArgChecks, SingleCompileSeveralModes1) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM | HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Compile a pattern with bogus flags
|
|
TEST(HyperscanArgChecks, SingleCompileBogusFlags) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0xdeadbeef, HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
EXPECT_STREQ("only HS_FLAG_QUIET and HS_FLAG_SINGLEMATCH "
|
|
"are supported in combination "
|
|
"with HS_FLAG_COMBINATION.", compile_err->message);
|
|
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Compile a pattern with bogus mode flags set.
|
|
TEST(HyperscanArgChecks, SingleCompileBogusMode1) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
|
|
unsigned mode = HS_MODE_STREAM | (1U << 30);
|
|
|
|
hs_error_t err = hs_compile("foobar", 0, mode, nullptr, &db, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
ASSERT_TRUE(compile_err != nullptr);
|
|
ASSERT_STREQ("Invalid parameter: unrecognised mode flags.",
|
|
compile_err->message);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SingleCompileBadTune) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_platform_info_t plat;
|
|
plat.cpu_features = 0;
|
|
plat.tune = 42;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, &plat, &db,
|
|
&compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
EXPECT_STREQ("Invalid tuning value specified in the platform information.",
|
|
compile_err->message);
|
|
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SingleCompileBadFeatures) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_platform_info_t plat;
|
|
plat.cpu_features = 42;
|
|
plat.tune = 0;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, &plat, &db,
|
|
&compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
EXPECT_STREQ("Invalid cpu features specified in the platform information.",
|
|
compile_err->message);
|
|
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Check SOM flag validation.
|
|
TEST(HyperscanArgChecks, SingleCompileSOMFlag) {
|
|
|
|
// try using the flags without a SOM mode.
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", HS_FLAG_SOM_LEFTMOST, HS_MODE_STREAM,
|
|
nullptr, &db, &compile_err);
|
|
ASSERT_EQ(HS_COMPILER_ERROR, err) << "should have failed with flag "
|
|
<< HS_FLAG_SOM_LEFTMOST;
|
|
ASSERT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile: Check SOM mode validation.
|
|
TEST(HyperscanArgChecks, SingleCompileSOMModes) {
|
|
static const unsigned som_modes[] = {
|
|
HS_MODE_SOM_HORIZON_LARGE,
|
|
HS_MODE_SOM_HORIZON_MEDIUM,
|
|
HS_MODE_SOM_HORIZON_SMALL
|
|
};
|
|
const size_t num_modes = sizeof(som_modes)/sizeof(som_modes[0]);
|
|
|
|
// compilation of a trivial case with a single mode set should be fine.
|
|
for (size_t i = 0; i < num_modes; i++) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", HS_FLAG_SOM_LEFTMOST,
|
|
HS_MODE_STREAM | som_modes[i], nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// you can only use one of the SOM modes at a time.
|
|
for (size_t i = 0; i < num_modes; i++) {
|
|
for (size_t j = i + 1; j < num_modes; j++) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
unsigned int mode = som_modes[i] | som_modes[j];
|
|
hs_error_t err = hs_compile("foobar", HS_FLAG_SOM_LEFTMOST,
|
|
HS_MODE_STREAM | mode, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_COMPILER_ERROR, err)
|
|
<< "should have failed with mode " << mode;
|
|
ASSERT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
}
|
|
}
|
|
|
|
// hs_compile_multi: Compile a NULL pattern set (block mode)
|
|
TEST(HyperscanArgChecks, MultiCompileBlockNoPattern) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile_multi(nullptr, nullptr, nullptr, 1, HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(db == nullptr);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile_multi: Compile a NULL pattern set (streaming mode)
|
|
TEST(HyperscanArgChecks, MultiCompileStreamingNoPattern) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile_multi(nullptr, nullptr, nullptr, 1, HS_MODE_STREAM,
|
|
nullptr, &db, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(db == nullptr);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile_multi: Compile a set of zero patterns
|
|
TEST(HyperscanArgChecks, MultiCompileZeroPatterns) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
const char *expr[] = {"foobar"};
|
|
hs_error_t err = hs_compile_multi(expr, nullptr, nullptr, 0, HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(db == nullptr);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile_multi: Compile a pattern to a NULL database ptr (block mode)
|
|
TEST(HyperscanArgChecks, MultiCompileBlockNoDatabase) {
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
const char *expr[] = {"foobar"};
|
|
hs_error_t err = hs_compile_multi(expr, nullptr, nullptr, 1, HS_MODE_NOSTREAM,
|
|
nullptr, nullptr, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_compile_multi: Compile a pattern to a NULL database ptr (streaming mode)
|
|
TEST(HyperscanArgChecks, MultiCompileStreamingNoDatabase) {
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
const char *expr[] = {"foobar"};
|
|
hs_error_t err = hs_compile_multi(expr, nullptr, nullptr, 1, HS_MODE_STREAM,
|
|
nullptr, nullptr, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_open_stream: Open a stream with a NULL database ptr
|
|
TEST(HyperscanArgChecks, OpenStreamNoDatabase) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_error_t err = hs_open_stream(nullptr, 0, &stream);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_TRUE(stream == nullptr);
|
|
}
|
|
|
|
// hs_open_stream: Open a stream with a NULL stream ptr
|
|
TEST(HyperscanArgChecks, OpenStreamNoStreamId) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_open_stream: Open a stream with a non-streaming database
|
|
TEST(HyperscanArgChecks, OpenStreamWithBlockDatabase) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_TRUE(stream == nullptr);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_open_stream: Open a stream with a broken database bytecode
|
|
TEST(HyperscanArgChecks, OpenStreamWithBrokenDatabaseBytecode) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
breakDatabaseBytecode(db);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_TRUE(stream == nullptr);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_stream: Call with no stream ID
|
|
TEST(HyperscanArgChecks, ScanStreamNoStreamID) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
err = hs_scan_stream(nullptr, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_stream: Call with no data
|
|
TEST(HyperscanArgChecks, ScanStreamNoData) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
hs_stream_t *stream = nullptr;
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_scan_stream(stream, nullptr, 4, 0, scratch, dummy_cb, nullptr);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_stream: Call with no scratch
|
|
TEST(HyperscanArgChecks, ScanStreamNoScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
hs_stream_t *stream = nullptr;
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_scan_stream(stream, nullptr, 4, 0, scratch, dummy_cb, nullptr);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_close_stream: Call with no stream
|
|
TEST(HyperscanArgChecks, CloseStreamNoStream) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
err = hs_close_stream(nullptr, scratch, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_close_stream: Call with no scratch
|
|
TEST(HyperscanArgChecks, CloseStreamNoScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_stream_t *stream = nullptr;
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_close_stream(stream, nullptr, dummy_cb, nullptr);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
|
|
// We happen to know we can free the stream here, and we do it so that
|
|
// this doesn't appear as a memory leak in valgrind
|
|
free(stream);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_close_stream: Call with no scratch and no callback (allowed)
|
|
TEST(HyperscanArgChecks, CloseStreamNoScratchNoCallback) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_stream_t *stream = nullptr;
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_close_stream(stream, nullptr, nullptr, nullptr);
|
|
EXPECT_EQ(HS_SUCCESS, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_close_stream_nomatch: Call with no stream
|
|
TEST(HyperscanArgChecks, CloseStreamNoMatchNoStream) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_close_stream(nullptr, scratch, nullptr, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_set_stream_context: change context
|
|
TEST(HyperscanArgChecks, ChangeStreamContext) {
|
|
const char *str = "foobar";
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile(str, 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
// we'll start with the context pointer set to the scratch space ...
|
|
hs_stream_t *stream = nullptr;
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
err = hs_scan_stream(stream, str, strlen(str), 0, scratch, singleHandler,
|
|
(void *)scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
ASSERT_EQ(lastMatchTo, strlen(str));
|
|
ASSERT_EQ(lastMatchCtx, scratch);
|
|
|
|
// ... and then change it to the stream ptr itself.
|
|
err = hs_scan_stream(stream, str, strlen(str), 0, scratch, singleHandler,
|
|
(void *)stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
ASSERT_EQ(lastMatchTo, 2*strlen(str));
|
|
ASSERT_EQ(lastMatchCtx, stream);
|
|
|
|
err = hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
// hs_reset_stream: Call with no stream id
|
|
TEST(HyperscanArgChecks, ResetStreamNoId) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_reset_stream(nullptr, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_reset_stream: Call with no scratch
|
|
TEST(HyperscanArgChecks, ResetStreamNoScratch) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_reset_stream(stream, 0, nullptr, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_copy_stream: Call with no from_id
|
|
TEST(HyperscanArgChecks, CopyStreamNoFromId) {
|
|
hs_stream_t *to;
|
|
hs_error_t err = hs_copy_stream(&to, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
// hs_copy_stream: Call with no to_id
|
|
TEST(HyperscanArgChecks, CopyStreamNoToId) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_copy_stream(nullptr, stream);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ResetAndCopyStreamNoToId) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_reset_and_copy_stream(nullptr, stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ResetAndCopyStreamNoFromId) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_reset_and_copy_stream(stream, nullptr, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ResetAndCopyStreamSameToId) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_reset_and_copy_stream(stream, stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_reset_and_copy_stream: You're allowed to reset and copy a stream with no
|
|
// scratch and no callback.
|
|
TEST(HyperscanArgChecks, ResetAndCopyStreamNoCallbackOrScratch) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_stream_t *stream_to = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream_to);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_reset_and_copy_stream(stream_to, stream, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_close_stream(stream_to, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_reset_and_copy_stream: If you specify a callback, you must provide
|
|
// scratch.
|
|
TEST(HyperscanArgChecks, ResetAndCopyStreamNoScratch) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_stream_t *stream_to = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream_to);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_reset_and_copy_stream(stream_to, stream, nullptr, dummy_cb,
|
|
nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream_to, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ResetAndCopyStreamDiffDb) {
|
|
hs_stream_t *stream = nullptr;
|
|
hs_stream_t *stream_to = nullptr;
|
|
hs_database_t *db = nullptr;
|
|
hs_database_t *db2 = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_compile("barfoo", 0, HS_MODE_STREAM, nullptr, &db2, &compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_alloc_scratch(db2, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_open_stream(db2, 0, &stream_to);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_reset_and_copy_stream(stream_to, stream, scratch, nullptr,
|
|
nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream_to, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
hs_free_database(db2);
|
|
}
|
|
|
|
// hs_scan: Call with no database
|
|
TEST(HyperscanArgChecks, ScanBlockNoDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
err = hs_scan(nullptr, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan: Call with a database with broken magic
|
|
TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseMagic) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
// break the database here, after scratch alloc
|
|
breakDatabaseMagic(db);
|
|
|
|
err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
free(db);
|
|
}
|
|
|
|
// hs_scan: Call with a database with broken version
|
|
TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseVersion) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
// break the database here, after scratch alloc
|
|
breakDatabaseVersion(db);
|
|
|
|
err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_DB_VERSION_ERROR, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan: Call with a database with broken bytecode offset
|
|
TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseBytecode) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
// break the database here, after scratch alloc
|
|
breakDatabaseBytecode(db);
|
|
|
|
err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan: Call with a database built for streaming mode
|
|
TEST(HyperscanArgChecks, ScanBlockStreamingDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ScanBlockVectoredDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
|
|
// hs_scan: Call with no data
|
|
TEST(HyperscanArgChecks, ScanBlockNoData) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
err = hs_scan(db, nullptr, 4, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan: Call with no scratch
|
|
TEST(HyperscanArgChecks, ScanBlockNoScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
err = hs_scan(db, "data", 4, 0, nullptr, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan: Call with no event handler
|
|
TEST(HyperscanArgChecks, ScanBlockNoHandler) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
err = hs_scan(db, "data", 4, 0, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with no database
|
|
TEST(HyperscanArgChecks, ScanVectorNoDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(nullptr, data, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with a database with broken magic
|
|
TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseMagic) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
// break the database here, after scratch alloc
|
|
breakDatabaseMagic(db);
|
|
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
free(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with a database with broken version
|
|
TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseVersion) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
// break the database here, after scratch alloc
|
|
breakDatabaseVersion(db);
|
|
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_DB_VERSION_ERROR, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with a database with broken bytecode offset
|
|
TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseBytecode) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
// break the database here, after scratch alloc
|
|
breakDatabaseBytecode(db);
|
|
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with a database built for streaming mode
|
|
TEST(HyperscanArgChecks, ScanVectorStreamingDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ScanVectorBlockDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_BLOCK, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with null data
|
|
TEST(HyperscanArgChecks, ScanVectorNoDataArray) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, nullptr, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ScanVectorNoDataBlock) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
const char *data[] = {"data", nullptr};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ScanVectorNoLenArray) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
|
|
const char *data[] = {"data", "data"};
|
|
err = hs_scan_vector(db, data, nullptr, 2, 0, scratch, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with no scratch
|
|
TEST(HyperscanArgChecks, ScanVectorNoScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, nullptr, dummy_cb, nullptr);
|
|
ASSERT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_vector: Call with no event handler
|
|
TEST(HyperscanArgChecks, ScanVectorNoHandler) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
const char *data[] = {"data", "data"};
|
|
unsigned int len[] = {4, 4};
|
|
err = hs_scan_vector(db, data, len, 2, 0, scratch, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with no database
|
|
TEST(HyperscanArgChecks, AllocScratchNoDatabase) {
|
|
hs_scratch_t *scratch = nullptr;
|
|
hs_error_t err = hs_alloc_scratch(nullptr, &scratch);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_TRUE(scratch == nullptr);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with NULL ptr-to-scratch
|
|
TEST(HyperscanArgChecks, AllocScratchNullScratchPtr) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
err = hs_alloc_scratch(db, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with bogus scratch
|
|
TEST(HyperscanArgChecks, AllocScratchBogusScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
hs_scratch_t *blah = (hs_scratch_t *)malloc(100);
|
|
ASSERT_TRUE(blah != nullptr);
|
|
memset(blah, 0xf0, 100);
|
|
err = hs_alloc_scratch(db, &blah);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
free(blah);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with broken database magic
|
|
TEST(HyperscanArgChecks, AllocScratchBadDatabaseMagic) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
breakDatabaseMagic(db);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
free(db);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with broken database version
|
|
TEST(HyperscanArgChecks, AllocScratchBadDatabaseVersion) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
breakDatabaseVersion(db);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_DB_VERSION_ERROR, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with broken database platform
|
|
TEST(HyperscanArgChecks, AllocScratchBadDatabasePlatform) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
breakDatabasePlatform(db);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_DB_PLATFORM_ERROR, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with broken database bytecode alignment
|
|
TEST(HyperscanArgChecks, AllocScratchBadDatabaseBytecode) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
breakDatabaseBytecode(db);
|
|
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_alloc_scratch: Call with broken database CRC
|
|
TEST(HyperscanArgChecks, AllocScratchBadDatabaseCRC) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t len = 0;
|
|
err = hs_database_size(db, &len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0U, len);
|
|
|
|
// ensure that we're able to alloc scratch for the unbroken db.
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
// for want of a better case, corrupt the "middle byte" of the database.
|
|
char *mid = (char *)db + len/2;
|
|
*mid += 17;
|
|
|
|
scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_clone_scratch: Call with no source scratch
|
|
TEST(HyperscanArgChecks, CloneScratchNoSource) {
|
|
hs_scratch_t *scratch = nullptr, *scratch2 = nullptr;
|
|
hs_error_t err = hs_clone_scratch(scratch, &scratch2);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_TRUE(scratch2 == nullptr);
|
|
}
|
|
|
|
// hs_serialize_database: Call with no database
|
|
TEST(HyperscanArgChecks, SerializeNoDatabase) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
hs_error_t err = hs_serialize_database(nullptr, &bytes, &length);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_TRUE(bytes == nullptr);
|
|
}
|
|
|
|
// hs_serialize_database: Call with no bytes ptr
|
|
TEST(HyperscanArgChecks, SerializeNoBuffer) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t length = 0;
|
|
err = hs_serialize_database(db, nullptr, &length);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_EQ(0U, length);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_serialize_database: Call with no bytes ptr
|
|
TEST(HyperscanArgChecks, SerializeNoLength) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
char *buf = nullptr;
|
|
err = hs_serialize_database(db, &buf, nullptr);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_TRUE(buf == nullptr);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_stream_size: Call with no database
|
|
TEST(HyperscanArgChecks, StreamSizeNoDatabase) {
|
|
size_t sz;
|
|
hs_error_t err = hs_stream_size(nullptr, &sz);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
// hs_stream_size: Call with invalid database
|
|
TEST(HyperscanArgChecks, StreamSizeBogusDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
size_t len;
|
|
err = hs_database_size(db, &len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_LT(0U, len);
|
|
|
|
memset(db, 0xf0, len);
|
|
|
|
size_t sz;
|
|
err = hs_stream_size(db, &sz);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
free(db);
|
|
}
|
|
|
|
// hs_stream_size: Call with a block-mode database
|
|
TEST(HyperscanArgChecks, StreamSizeBlockDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t sz;
|
|
err = hs_stream_size(db, &sz);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, StreamSizeVectoredDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t sz;
|
|
err = hs_stream_size(db, &sz);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, OpenStreamBlockDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
hs_stream_t *id;
|
|
err = hs_open_stream(db, 0, &id);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, OpenStreamVectoredDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
hs_stream_t *id;
|
|
err = hs_open_stream(db, 0, &id);
|
|
ASSERT_EQ(HS_DB_MODE_ERROR, err);
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
|
|
// hs_stream_size: Call with a real database
|
|
TEST(HyperscanArgChecks, StreamSizeRealDatabase) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t sz;
|
|
err = hs_stream_size(db, &sz);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0U, sz)
|
|
<< "Stream-mode database should have non-zero stream size";
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, StreamSizeNoSize) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
err = hs_stream_size(db, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_database_size: Call with no database
|
|
TEST(HyperscanArgChecks, DatabaseSizeNoDatabase) {
|
|
size_t sz;
|
|
hs_error_t err = hs_database_size(nullptr, &sz);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DatabaseSizeNoSize) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
err = hs_database_size(db, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DatabaseSizeBadDb) {
|
|
hs_database_t *db = (hs_database_t *)garbage;
|
|
size_t sz;
|
|
|
|
hs_error_t err = hs_database_size(db, &sz);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DatabaseInfoBadDb) {
|
|
hs_database_t *db = (hs_database_t *)garbage;
|
|
char *info = garbage;
|
|
hs_error_t err = hs_database_info(db, &info);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
ASSERT_TRUE(nullptr == info);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DatabaseInfoNullDb) {
|
|
char *info = garbage;
|
|
hs_error_t err = hs_database_info(nullptr, &info);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
ASSERT_TRUE(nullptr == info);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DatabaseInfoNullInfo) {
|
|
hs_database_t *db;
|
|
hs_compile_error_t *c_err;
|
|
static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
|
|
|
|
hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
err = hs_database_info(db, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SerializedDatabaseSizeBadLen) {
|
|
hs_database_t *db;
|
|
hs_compile_error_t *c_err;
|
|
static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
|
|
|
|
hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t db_len;
|
|
err = hs_database_size(db, &db_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, db_len);
|
|
|
|
char *bytes = nullptr;
|
|
size_t bytes_len = 0;
|
|
|
|
err = hs_serialize_database(db, &bytes, &bytes_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, bytes_len);
|
|
|
|
hs_free_database(db);
|
|
|
|
size_t ser_len;
|
|
err = hs_serialized_database_size(bytes, 16, &ser_len);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SerializedDatabaseSizeNoSize) {
|
|
hs_database_t *db;
|
|
hs_compile_error_t *c_err;
|
|
static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
|
|
|
|
hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t db_len;
|
|
err = hs_database_size(db, &db_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, db_len);
|
|
|
|
char *bytes = nullptr;
|
|
size_t bytes_len = 0;
|
|
|
|
err = hs_serialize_database(db, &bytes, &bytes_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, bytes_len);
|
|
|
|
hs_free_database(db);
|
|
|
|
err = hs_serialized_database_size(bytes, bytes_len, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SerializedDatabaseSizeNoBytes) {
|
|
size_t sz;
|
|
hs_error_t err = hs_serialized_database_size(nullptr, 1024, &sz);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SerializedDatabaseInfoBadLen) {
|
|
hs_database_t *db;
|
|
hs_compile_error_t *c_err;
|
|
static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
|
|
|
|
hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t db_len;
|
|
err = hs_database_size(db, &db_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, db_len);
|
|
|
|
char *bytes = nullptr;
|
|
size_t bytes_len = 0;
|
|
|
|
err = hs_serialize_database(db, &bytes, &bytes_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, bytes_len);
|
|
|
|
hs_free_database(db);
|
|
|
|
char *info = garbage;
|
|
err = hs_serialized_database_info(bytes, 16, &info);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
ASSERT_TRUE(nullptr == info);
|
|
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SerializedDatabaseInfoNoInfo) {
|
|
hs_database_t *db;
|
|
hs_compile_error_t *c_err;
|
|
static const char *pattern = "hatstand.*(badgerbrush|teakettle)";
|
|
|
|
hs_error_t err = hs_compile(pattern, 0, HS_MODE_NOSTREAM, nullptr, &db, &c_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
size_t db_len;
|
|
err = hs_database_size(db, &db_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, db_len);
|
|
|
|
char *bytes = nullptr;
|
|
size_t bytes_len = 0;
|
|
|
|
err = hs_serialize_database(db, &bytes, &bytes_len);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_NE(0, bytes_len);
|
|
|
|
hs_free_database(db);
|
|
|
|
err = hs_serialized_database_info(bytes, bytes_len, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, SerializedDatabaseInfoNoBytes) {
|
|
char *info = garbage;
|
|
hs_error_t err = hs_serialized_database_info(nullptr, 1024, &info);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
ASSERT_TRUE(nullptr == info);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseNoBytes) {
|
|
hs_database_t *db = nullptr;
|
|
hs_error_t err = hs_deserialize_database(nullptr, 2048, &db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseAtNoBytes) {
|
|
hs_database_t *db = nullptr;
|
|
hs_error_t err = hs_deserialize_database_at(nullptr, 2048, db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
static
|
|
void makeSerializedDatabase(char **bytes, size_t *length) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_BLOCK);
|
|
ASSERT_NE(nullptr, db);
|
|
hs_error_t err = hs_serialize_database(db, bytes, length);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseNoDb) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
hs_error_t err = hs_deserialize_database(bytes, length, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseBadLen) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
hs_database_t *db = nullptr;
|
|
hs_error_t err = hs_deserialize_database(bytes, length - 1, &db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseBadLen2) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
hs_database_t *db = nullptr;
|
|
hs_error_t err = hs_deserialize_database(bytes, length + 1, &db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseBadBytes) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
memset(bytes, 0xff, length); // scribble
|
|
hs_database_t *db = nullptr;
|
|
hs_error_t err = hs_deserialize_database(bytes, length, &db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseBadBytes2) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
memset(bytes, 0, length); // scribble
|
|
hs_database_t *db = nullptr;
|
|
hs_error_t err = hs_deserialize_database(bytes, length, &db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseAtNoDb) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
hs_error_t err = hs_deserialize_database_at(bytes, length, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseAtBadLen) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
size_t db_length = 0;
|
|
hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_database_t *db = (hs_database_t *)malloc(db_length);
|
|
err = hs_deserialize_database_at(bytes, length - 1, db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
free(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseAtBadLen2) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
size_t db_length = 0;
|
|
hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_database_t *db = (hs_database_t *)malloc(db_length);
|
|
err = hs_deserialize_database_at(bytes, length + 1, db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
free(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseAtBadBytes) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
size_t db_length = 0;
|
|
hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_database_t *db = (hs_database_t *)malloc(db_length);
|
|
memset(bytes, 0xff, length); // scribble
|
|
err = hs_deserialize_database_at(bytes, length, db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
free(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, DeserializeDatabaseAtBadBytes2) {
|
|
char *bytes = nullptr;
|
|
size_t length = 0;
|
|
makeSerializedDatabase(&bytes, &length);
|
|
size_t db_length = 0;
|
|
hs_error_t err = hs_serialized_database_size(bytes, length, &db_length);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_database_t *db = (hs_database_t *)malloc(db_length);
|
|
memset(bytes, 0, length); // scribble
|
|
err = hs_deserialize_database_at(bytes, length, db);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
free(bytes);
|
|
free(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ScratchSizeNoSize) {
|
|
hs_error_t err;
|
|
|
|
// build a database
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
err = hs_compile("foo.*bar$", 0, HS_MODE_STREAM, nullptr, &db, &compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
// alloc some scratch
|
|
hs_scratch_t *scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
EXPECT_TRUE(scratch != nullptr);
|
|
|
|
err = hs_scratch_size(scratch, nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ScratchSizeNoScratch) {
|
|
size_t size;
|
|
hs_error_t err = hs_scratch_size(nullptr, &size);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ScratchSizeBadScratch) {
|
|
hs_scratch_t *scratch = (hs_scratch_t *)garbage;
|
|
size_t size;
|
|
hs_error_t err = hs_scratch_size(scratch, &size);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
// hs_clone_scratch: bad scratch arg
|
|
TEST(HyperscanArgChecks, CloneBadScratch) {
|
|
// Try cloning the scratch
|
|
void *local_garbage = malloc(sizeof(garbage));
|
|
ASSERT_TRUE(local_garbage != nullptr);
|
|
memcpy(local_garbage, garbage, sizeof(garbage));
|
|
hs_scratch_t *cloned = nullptr;
|
|
hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
|
|
hs_error_t err = hs_clone_scratch(scratch, &cloned);
|
|
free(local_garbage);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
// hs_scan: bad scratch arg
|
|
TEST(HyperscanArgChecks, ScanBadScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
|
|
void *local_garbage = malloc(sizeof(garbage));
|
|
ASSERT_TRUE(local_garbage != nullptr);
|
|
memcpy(local_garbage, garbage, sizeof(garbage));
|
|
|
|
hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
|
|
err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr);
|
|
free(local_garbage);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
|
|
// hs_scan_stream: bad scratch arg
|
|
TEST(HyperscanArgChecks, ScanStreamBadScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
void *local_garbage = malloc(sizeof(garbage));
|
|
ASSERT_TRUE(local_garbage != nullptr);
|
|
memcpy(local_garbage, garbage, sizeof(garbage));
|
|
hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
|
|
|
|
hs_stream_t *stream = nullptr;
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_scan_stream(stream, "data", 4, 0, scratch, nullptr, nullptr);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
|
|
EXPECT_EQ(HS_INVALID, err);
|
|
scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
hs_free_database(db);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
free(local_garbage);
|
|
}
|
|
|
|
// hs_reset_stream: bad scratch arg
|
|
TEST(HyperscanArgChecks, ResetStreamBadScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_STREAM, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
void *local_garbage = malloc(sizeof(garbage));
|
|
ASSERT_TRUE(local_garbage != nullptr);
|
|
memcpy(local_garbage, garbage, sizeof(garbage));
|
|
hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
|
|
|
|
hs_stream_t *stream = nullptr;
|
|
err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(stream != nullptr);
|
|
|
|
err = hs_reset_stream(stream, 0, scratch, dummy_cb, nullptr);
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
err = hs_close_stream(stream, scratch, dummy_cb, nullptr);
|
|
EXPECT_EQ(HS_INVALID, err);
|
|
scratch = nullptr;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != nullptr);
|
|
hs_close_stream(stream, scratch, nullptr, nullptr);
|
|
hs_free_database(db);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
free(local_garbage);
|
|
}
|
|
|
|
// hs_scan_stream: bad scratch arg
|
|
TEST(HyperscanArgChecks, ScanVectorBadScratch) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_VECTORED, nullptr, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != nullptr);
|
|
void *local_garbage = malloc(sizeof(garbage));
|
|
ASSERT_TRUE(local_garbage != nullptr);
|
|
memcpy(local_garbage, garbage, sizeof(garbage));
|
|
hs_scratch_t *scratch = (hs_scratch_t *)local_garbage;
|
|
|
|
const char *data[] = { "data" };
|
|
unsigned int len[] = { 4 };
|
|
|
|
err = hs_scan_vector(db, data, len, 1, 0, scratch, dummy_cb, nullptr);
|
|
|
|
EXPECT_NE(HS_SUCCESS, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
free(local_garbage);
|
|
}
|
|
|
|
// hs_scan: bad (freed) scratch arg
|
|
// disabled as, unsurprisingly, valgrind complains
|
|
#ifdef TEST_FREED_MEM
|
|
TEST(HyperscanArgChecks, ScanFreedScratch) {
|
|
hs_database_t *db = 0;
|
|
hs_compile_error_t *compile_err = 0;
|
|
hs_error_t err = hs_compile("foobar", 0, HS_MODE_NOSTREAM, NULL, &db,
|
|
&compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(db != NULL);
|
|
hs_scratch_t *scratch = 0;
|
|
err = hs_alloc_scratch(db, &scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
ASSERT_TRUE(scratch != NULL);
|
|
err = hs_free_scratch(scratch);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, 0);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
EXPECT_NE(HS_SCAN_TERMINATED, err);
|
|
|
|
// teardown
|
|
hs_free_database(db);
|
|
}
|
|
#endif // TEST_FREED_MEM
|
|
|
|
// hs_expression_info: Compile a NULL pattern
|
|
TEST(HyperscanArgChecks, ExprInfoNullExpression) {
|
|
hs_expr_info_t *info = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_expression_info(nullptr, 0, &info, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(info == nullptr);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_expression_info: NULL info block ptr
|
|
TEST(HyperscanArgChecks, ExprInfoNullInfoPtr) {
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err = hs_expression_info("foobar", 0, nullptr, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_expression_info: No compiler error block
|
|
TEST(HyperscanArgChecks, ExprInfoNullErrPtr) {
|
|
hs_expr_info_t *info = nullptr;
|
|
hs_error_t err = hs_expression_info("foobar", 0, &info, nullptr);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(info == nullptr);
|
|
}
|
|
|
|
// hs_expression_ext_info: Compile a NULL pattern
|
|
TEST(HyperscanArgChecks, ExprExtInfoNullExpression) {
|
|
hs_expr_info_t *info = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err =
|
|
hs_expression_ext_info(nullptr, 0, nullptr, &info, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(info == nullptr);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_expression_ext_info: NULL info block ptr
|
|
TEST(HyperscanArgChecks, ExprExtInfoNullInfoPtr) {
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
hs_error_t err =
|
|
hs_expression_ext_info("foobar", 0, nullptr, nullptr, &compile_err);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(compile_err != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
// hs_expression_ext_info: No compiler error block
|
|
TEST(HyperscanArgChecks, ExprExtInfoNullErrPtr) {
|
|
hs_expr_info_t *info = nullptr;
|
|
hs_error_t err =
|
|
hs_expression_ext_info("foobar", 0, nullptr, &info, nullptr);
|
|
EXPECT_EQ(HS_COMPILER_ERROR, err);
|
|
EXPECT_TRUE(info == nullptr);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, hs_free_database_null) {
|
|
hs_error_t err = hs_free_database(nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, hs_free_database_garbage) {
|
|
hs_error_t err = hs_free_database((hs_database_t *)garbage);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, hs_free_scratch_null) {
|
|
hs_error_t err = hs_free_scratch(nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, hs_free_scratch_garbage) {
|
|
hs_error_t err = hs_free_scratch((hs_scratch_t *)garbage);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, hs_free_compile_error_null) {
|
|
hs_error_t err = hs_free_compile_error(nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, multicompile_mix_highlander_1) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
|
|
unsigned flags[] = {HS_FLAG_SINGLEMATCH, 0};
|
|
unsigned ids[] = {30, 30};
|
|
hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
ASSERT_EQ(HS_COMPILER_ERROR, err);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, multicompile_mix_highlander_2) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
|
|
unsigned flags[] = {0, HS_FLAG_SINGLEMATCH};
|
|
unsigned ids[] = {30, 30};
|
|
hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
ASSERT_EQ(HS_COMPILER_ERROR, err);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, multicompile_nomix_highlander_1) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
|
|
unsigned flags[] = {HS_FLAG_SINGLEMATCH, HS_FLAG_SINGLEMATCH};
|
|
unsigned ids[] = {30, 30};
|
|
hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, multicompile_nomix_highlander_2) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
const char *expr[] = {"aoo[A-K]", "bar[L-Z]"};
|
|
unsigned flags[] = {0, 0};
|
|
unsigned ids[] = {30, 30};
|
|
hs_error_t err = hs_compile_multi(expr, flags, ids, 2, HS_MODE_NOSTREAM,
|
|
nullptr, &db, &compile_err);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
hs_free_database(db);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, hs_populate_platform_null) {
|
|
hs_error_t err = hs_populate_platform(nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, CompressStreamNoStream) {
|
|
char buf[100];
|
|
size_t used;
|
|
hs_error_t err = hs_compress_stream(nullptr, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, CompressStreamNoUsed) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[100];
|
|
err = hs_compress_stream(stream, buf, sizeof(buf), nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, CompressStreamNoBuf) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[100];
|
|
size_t used;
|
|
err = hs_compress_stream(stream, nullptr, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, CompressStreamSmallBuff) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[100];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream, buf, 1, &used);
|
|
ASSERT_EQ(HS_INSUFFICIENT_SPACE, err);
|
|
ASSERT_LT(0, used);
|
|
|
|
err = hs_close_stream(stream, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ExpandNoDb) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_stream_t *stream2;
|
|
err = hs_expand_stream(nullptr, &stream2, buf, used);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ExpandNoTo) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_stream_t *stream2;
|
|
err = hs_expand_stream(db, nullptr, buf, used);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ExpandNoBuf) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_stream_t *stream2;
|
|
err = hs_expand_stream(db, &stream2, nullptr, used);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ExpandSmallBuf) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_stream_t *stream2;
|
|
err = hs_expand_stream(db, &stream2, buf, used / 2);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ResetAndExpandNoStream) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_reset_and_expand_stream(nullptr, buf, used, nullptr, nullptr,
|
|
nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ResetAndExpandNoBuf) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_stream_t *stream2;
|
|
err = hs_open_stream(db, 0, &stream2);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_reset_and_expand_stream(stream2, nullptr, used, nullptr, nullptr,
|
|
nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_close_stream(stream2, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
|
|
TEST(HyperscanArgChecks, ResetAndExpandSmallBuf) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_stream_t *stream2;
|
|
err = hs_open_stream(db, 0, &stream2);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_reset_and_expand_stream(stream2, buf, used / 2, nullptr, nullptr,
|
|
nullptr);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_close_stream(stream2, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
TEST(HyperscanArgChecks, ResetAndExpandNoScratch) {
|
|
hs_database_t *db = buildDB("(foo.*bar){3,}", 0, 0, HS_MODE_STREAM);
|
|
ASSERT_NE(nullptr, db);
|
|
|
|
hs_stream_t *stream1;
|
|
hs_error_t err = hs_open_stream(db, 0, &stream1);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
char buf[2000];
|
|
size_t used = 0;
|
|
err = hs_compress_stream(stream1, buf, sizeof(buf), &used);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
hs_stream_t *stream2;
|
|
err = hs_open_stream(db, 0, &stream2);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
int temp;
|
|
|
|
err = hs_reset_and_expand_stream(stream2, buf, used, nullptr, singleHandler,
|
|
&temp);
|
|
ASSERT_EQ(HS_INVALID, err);
|
|
|
|
err = hs_close_stream(stream1, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_close_stream(stream2, nullptr, nullptr, nullptr);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
|
|
err = hs_free_database(db);
|
|
ASSERT_EQ(HS_SUCCESS, err);
|
|
}
|
|
|
|
class BadModeTest : public testing::TestWithParam<unsigned> {};
|
|
|
|
// hs_compile: Compile a pattern with bogus mode flags set.
|
|
TEST_P(BadModeTest, FailCompile) {
|
|
hs_database_t *db = nullptr;
|
|
hs_compile_error_t *compile_err = nullptr;
|
|
|
|
unsigned mode = GetParam();
|
|
SCOPED_TRACE(mode);
|
|
|
|
hs_error_t err = hs_compile("foo", 0, mode, nullptr, &db, &compile_err);
|
|
ASSERT_EQ(HS_COMPILER_ERROR, err);
|
|
ASSERT_TRUE(compile_err != nullptr);
|
|
ASSERT_TRUE(compile_err->message != nullptr);
|
|
hs_free_compile_error(compile_err);
|
|
}
|
|
|
|
static const unsigned badModeValues[] = {
|
|
// Multiple modes at once.
|
|
HS_MODE_BLOCK | HS_MODE_STREAM | HS_MODE_VECTORED,
|
|
HS_MODE_BLOCK | HS_MODE_STREAM,
|
|
HS_MODE_BLOCK | HS_MODE_VECTORED,
|
|
HS_MODE_STREAM | HS_MODE_VECTORED,
|
|
// SOM horizon modes are only accepted in streaming mode.
|
|
HS_MODE_BLOCK | HS_MODE_SOM_HORIZON_LARGE,
|
|
HS_MODE_BLOCK | HS_MODE_SOM_HORIZON_MEDIUM,
|
|
HS_MODE_BLOCK | HS_MODE_SOM_HORIZON_SMALL,
|
|
HS_MODE_VECTORED | HS_MODE_SOM_HORIZON_LARGE,
|
|
HS_MODE_VECTORED | HS_MODE_SOM_HORIZON_MEDIUM,
|
|
HS_MODE_VECTORED | HS_MODE_SOM_HORIZON_SMALL,
|
|
// Can't specify more than one SOM horizon.
|
|
HS_MODE_STREAM | HS_MODE_SOM_HORIZON_LARGE | HS_MODE_SOM_HORIZON_MEDIUM | HS_MODE_SOM_HORIZON_SMALL,
|
|
HS_MODE_STREAM | HS_MODE_SOM_HORIZON_LARGE | HS_MODE_SOM_HORIZON_SMALL,
|
|
HS_MODE_STREAM | HS_MODE_SOM_HORIZON_LARGE | HS_MODE_SOM_HORIZON_MEDIUM,
|
|
HS_MODE_STREAM | HS_MODE_SOM_HORIZON_MEDIUM | HS_MODE_SOM_HORIZON_SMALL,
|
|
};
|
|
|
|
INSTANTIATE_TEST_CASE_P(HyperscanArgChecks, BadModeTest,
|
|
testing::ValuesIn(badModeValues));
|
|
|
|
} // namespace
|
|
|