mirror of
https://github.com/VectorCamp/vectorscan.git
synced 2025-06-28 16:41:01 +03:00
Add test suite for the Direct API
Signed-off-by: Yoan Picchi <yoan.picchi@arm.com>
This commit is contained in:
parent
e91c75f139
commit
5782780e11
@ -63,6 +63,21 @@ set(unit_hyperscan_SOURCES
|
|||||||
add_executable(unit-hyperscan ${unit_hyperscan_SOURCES})
|
add_executable(unit-hyperscan ${unit_hyperscan_SOURCES})
|
||||||
target_link_libraries(unit-hyperscan hs expressionutil)
|
target_link_libraries(unit-hyperscan hs expressionutil)
|
||||||
|
|
||||||
|
set(unit_direct_api_SOURCES
|
||||||
|
${gtest_SOURCES}
|
||||||
|
direct_API/char_pair_set.cpp
|
||||||
|
direct_API/char_set.cpp
|
||||||
|
direct_API/common.h
|
||||||
|
direct_API/long_literal.cpp
|
||||||
|
direct_API/main.cpp
|
||||||
|
direct_API/multi_literal.cpp
|
||||||
|
direct_API/short_literal.cpp
|
||||||
|
direct_API/single_char_pair.cpp
|
||||||
|
direct_API/single_char.cpp
|
||||||
|
)
|
||||||
|
add_executable(unit-direct-API ${unit_direct_api_SOURCES})
|
||||||
|
target_link_libraries(unit-direct-API hs)
|
||||||
|
|
||||||
if (NOT FAT_RUNTIME AND BUILD_STATIC_LIBS)
|
if (NOT FAT_RUNTIME AND BUILD_STATIC_LIBS)
|
||||||
set(BUILD_UNIT_INTERNAL TRUE)
|
set(BUILD_UNIT_INTERNAL TRUE)
|
||||||
set(unit_internal_SOURCES
|
set(unit_internal_SOURCES
|
||||||
|
378
unit/direct_API/char_pair_set.cpp
Normal file
378
unit/direct_API/char_pair_set.cpp
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "common.h"
|
||||||
|
|
||||||
|
#include "hwlm/noodle_internal.h"
|
||||||
|
|
||||||
|
#define COMPILE_CHAR_PAIR_SET(in_character_array, in_pair_count) \
|
||||||
|
const size_t pair_count = (in_pair_count); \
|
||||||
|
const char *character_array = (in_character_array); \
|
||||||
|
hs_char_pair_set_compiled_pattern_t *database = nullptr; \
|
||||||
|
hs_error_t compile_ret = hs_compile_char_pair_set_search( \
|
||||||
|
character_array, pair_count, &database); \
|
||||||
|
hs_error_t ret = 0; \
|
||||||
|
(void)ret; /* suppress a cppcheck warning when SEARCH is not called */ \
|
||||||
|
const char *buffer = nullptr; \
|
||||||
|
(void)buffer; \
|
||||||
|
context_t context = {}; \
|
||||||
|
(void) context;
|
||||||
|
|
||||||
|
#define SEARCH_CHAR_PAIR_SET(in_buffer, in_buffer_len, in_expected_match, \
|
||||||
|
in_expected_start_array, in_expected_id_array) \
|
||||||
|
{ \
|
||||||
|
buffer = (in_buffer); \
|
||||||
|
const size_t buffer_len = (in_buffer_len); \
|
||||||
|
const size_t expected_match = (in_expected_match); \
|
||||||
|
size_t expected_start_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_end_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_id_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_id_array; \
|
||||||
|
for (size_t i = 0; i < expected_match; i++) { \
|
||||||
|
expected_end_array[i] += 2; \
|
||||||
|
} \
|
||||||
|
context.expected_start_array = expected_start_array; \
|
||||||
|
context.expected_end_array = expected_end_array; \
|
||||||
|
context.expected_id_array = expected_id_array; \
|
||||||
|
context.array_size = expected_match; \
|
||||||
|
context.number_matched = 0; \
|
||||||
|
context.number_wrong = 0; \
|
||||||
|
\
|
||||||
|
ret = hs_char_pair_set_search(database, buffer, buffer_len, callback, \
|
||||||
|
&context); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------free tests-------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_free_char_pair_set_pattern
|
||||||
|
nullptr
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(char_pair_set_free, nullptr) {
|
||||||
|
hs_char_pair_set_compiled_pattern_t *database = nullptr;
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_free, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
noodTable *clear_database =
|
||||||
|
reinterpret_cast<noodTable *>(test_malloc(sizeof(noodTable)));
|
||||||
|
|
||||||
|
hs_char_pair_set_compiled_pattern_t *database =
|
||||||
|
reinterpret_cast<hs_char_pair_set_compiled_pattern_t*>(clear_database);
|
||||||
|
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------compile tests----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_compile_char_pair_set_search
|
||||||
|
single pair
|
||||||
|
multiple pair
|
||||||
|
pair duplicate
|
||||||
|
valid pair including null char
|
||||||
|
|
||||||
|
empty char array
|
||||||
|
nullptr char array
|
||||||
|
nullptr output
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(char_pair_set_compile, single_pair) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
(void) ret;
|
||||||
|
(void) buffer;
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_pair_set_single_pair");
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_compile, two_pairs) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 2);
|
||||||
|
(void) ret;
|
||||||
|
(void) buffer;
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_pair_set_two_pairs");
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_compile, duplicate) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_AB_DUPLICATE, 2);
|
||||||
|
(void) ret;
|
||||||
|
(void) buffer;
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_pair_set_duplicate");
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_compile, null_char) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_A_NULL_BC, 1);
|
||||||
|
(void) ret;
|
||||||
|
(void) buffer;
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_pair_set_null_char");
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(char_pair_set_compile, no_expression) {
|
||||||
|
const size_t pair_count = 0;
|
||||||
|
const char *character_array = PAIR_SET_ABCD;
|
||||||
|
hs_char_pair_set_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_char_pair_set_search(character_array, pair_count,
|
||||||
|
&database),
|
||||||
|
"called with an empty set");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_compile, nullptr_char_array) {
|
||||||
|
hs_char_pair_set_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
hs_compile_char_pair_set_search(nullptr, 1, &database),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_compile, nullptr_database) {
|
||||||
|
const size_t pair_count = 2;
|
||||||
|
const char *character_array = PAIR_SET_ABCD;
|
||||||
|
EXPECT_DEATH(hs_compile_char_pair_set_search(character_array,
|
||||||
|
pair_count, nullptr),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------search tests-----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_char_pair_set_search
|
||||||
|
general pattern
|
||||||
|
match at start
|
||||||
|
match middle (general)
|
||||||
|
match index 15 (cross over vector)
|
||||||
|
match at end
|
||||||
|
match past end
|
||||||
|
match null char
|
||||||
|
bad caseness
|
||||||
|
search several times
|
||||||
|
match a pair duplicate
|
||||||
|
match several pattern in the same search
|
||||||
|
match when there's more pairs than fit in a vector
|
||||||
|
buffer containing null char
|
||||||
|
pattern with null char
|
||||||
|
general pattern
|
||||||
|
|
||||||
|
buff size 0
|
||||||
|
nullptr pattern
|
||||||
|
nullptr buffer
|
||||||
|
nullptr callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, start) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_start");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_0, EXPR_NOISE_LEN, 1, (0), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_general");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, cross_vector) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_cross_vector");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15), (0, 0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, end) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_end");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN, 1, (30), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, past_end) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_past_end");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN - 1, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, null_char) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_A_NULL_BC, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_null_char");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, bad_case) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_bad_case");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5_15_BAD_CASE, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, several_search) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_several_search");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15), (0, 0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, duplicate) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_AB_DUPLICATE, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("char_pair_set_search_duplicate");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, match_multiple) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_match_multiple");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 2, (5, 7), (0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, last_of_long_pattern) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_LONG_PATTERN_AB, 9);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_last_of_long_pattern");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (8));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, null_char_buff_and_pattern) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_A_NULL_BC, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS(
|
||||||
|
"test_char_pair_set_search_null_char_buff_and_pattern");
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, null_char_buff) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_null_char_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, empty_buff) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_empty_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_CHAR_PAIR_SET("", 0, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_pair_set_search", character_array, buffer);
|
||||||
|
hs_free_char_pair_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, nullptr_pattern) {
|
||||||
|
const hs_char_pair_set_compiled_pattern_t *database = nullptr;
|
||||||
|
context_t context;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
const char *buffer;
|
||||||
|
hs_error_t ret;
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_CHAR_PAIR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
},
|
||||||
|
"called with nullptr database");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, nullptr_buffer) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_nullptr_buffer");
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_CHAR_PAIR_SET(nullptr, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
},
|
||||||
|
"called with nullptr buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_pair_set_search, nullptr_callback) {
|
||||||
|
COMPILE_CHAR_PAIR_SET(PAIR_SET_ABCD, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_pair_set_search_nullptr_callback");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 1;
|
||||||
|
size_t expected_start_array[expected_match] = {5};
|
||||||
|
size_t expected_end_array[expected_match] = {5};
|
||||||
|
size_t expected_id_array[expected_match] = {0};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
expected_end_array[i] += 2;
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.expected_id_array = expected_id_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
hs_char_pair_set_search(database, buffer, buffer_len, nullptr,
|
||||||
|
&context);
|
||||||
|
},
|
||||||
|
"called with nullptr callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
333
unit/direct_API/char_set.cpp
Normal file
333
unit/direct_API/char_set.cpp
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "common.h"
|
||||||
|
|
||||||
|
#define COMPILE_CHAR_SET(in_character_array, in_character_count) \
|
||||||
|
const size_t character_count = (in_character_count); \
|
||||||
|
const char *character_array = (in_character_array); \
|
||||||
|
hs_char_set_compiled_pattern_t *database = nullptr; \
|
||||||
|
hs_error_t compile_ret = hs_compile_char_set_search( \
|
||||||
|
character_array, character_count, &database); \
|
||||||
|
hs_error_t ret = 0; \
|
||||||
|
(void)ret; /* suppress a cppcheck warning when SEARCH is not called */ \
|
||||||
|
const char *buffer = nullptr; \
|
||||||
|
(void)buffer; \
|
||||||
|
context_t context = {}; \
|
||||||
|
(void) context;
|
||||||
|
|
||||||
|
#define SEARCH_CHAR_SET(in_buffer, in_buffer_len, in_expected_match, \
|
||||||
|
in_expected_start_array, in_expected_id_array) \
|
||||||
|
{ \
|
||||||
|
buffer = (in_buffer); \
|
||||||
|
const size_t buffer_len = (in_buffer_len); \
|
||||||
|
const size_t expected_match = (in_expected_match); \
|
||||||
|
size_t expected_start_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_end_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_id_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_id_array; \
|
||||||
|
for (size_t i = 0; i < expected_match; i++) { \
|
||||||
|
expected_end_array[i] += 1; \
|
||||||
|
} \
|
||||||
|
context.expected_start_array = expected_start_array; \
|
||||||
|
context.expected_end_array = expected_end_array; \
|
||||||
|
context.expected_id_array = expected_id_array; \
|
||||||
|
context.array_size = expected_match; \
|
||||||
|
context.number_matched = 0; \
|
||||||
|
context.number_wrong = 0; \
|
||||||
|
\
|
||||||
|
ret = hs_char_set_search(database, buffer, buffer_len, callback, \
|
||||||
|
&context); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------free tests-------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_free_char_set_pattern
|
||||||
|
nullptr
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(char_set_free, nullptr) {
|
||||||
|
hs_char_set_compiled_pattern_t *database = nullptr;
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_free, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
truffle_storage *clear_database = reinterpret_cast<truffle_storage *>(
|
||||||
|
test_malloc(sizeof(truffle_storage)));
|
||||||
|
|
||||||
|
hs_char_set_compiled_pattern_t *database =
|
||||||
|
reinterpret_cast<hs_char_set_compiled_pattern_t*>(clear_database);
|
||||||
|
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------compile tests----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_compile_char_set_search
|
||||||
|
single char
|
||||||
|
same char twice
|
||||||
|
general (several different chars)
|
||||||
|
null char
|
||||||
|
|
||||||
|
empty char array
|
||||||
|
nullptr char array
|
||||||
|
nullptr output
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(char_set_compile, single_char) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_A, 1);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_set_single_char");
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_compile, single_char_twice) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_A, 2);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_set_single_char_twice");
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_compile, general) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_ABCDE, 5);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_set_general");
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_compile, null_char) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_NULL, 1);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_char_set_null_char");
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(char_set_compile, no_expression) {
|
||||||
|
const size_t character_count = 0;
|
||||||
|
const char *character_array = CHAR_SET_AB;
|
||||||
|
hs_char_set_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_char_set_search(character_array, character_count,
|
||||||
|
&database),
|
||||||
|
"called with an empty set");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_compile, nullptr_char_array) {
|
||||||
|
hs_char_set_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_char_set_search(nullptr, 1, &database),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_compile, nullptr_database) {
|
||||||
|
const size_t character_count = 2;
|
||||||
|
const char *character_array = CHAR_SET_AB;
|
||||||
|
EXPECT_DEATH(hs_compile_char_set_search(character_array,
|
||||||
|
character_count, nullptr),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------search tests-----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_char_set_search
|
||||||
|
match at start
|
||||||
|
match middle (general)
|
||||||
|
match index 15 (last char of a vector)
|
||||||
|
match at end
|
||||||
|
match past end
|
||||||
|
match null char
|
||||||
|
bad caseness
|
||||||
|
search several times
|
||||||
|
match first char
|
||||||
|
match last char
|
||||||
|
buff size 0
|
||||||
|
|
||||||
|
nullptr pattern
|
||||||
|
nullptr buffer
|
||||||
|
nullptr callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(char_set_search, start) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_start");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_0, EXPR_NOISE_LEN, 2, (0, 1), (0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_general");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 2, (5, 6), (0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, cross_vector) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_cross_vector");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 4, (5, 6, 15, 16),
|
||||||
|
(0, 1, 0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, end) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_end");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN, 2, (30, 31), (0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, past_end) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_past_end");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN - 1, 1, (30), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, null_char) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_NULL, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_null_char");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (6), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, bad_case) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_bad_case");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_5_15_BAD_CASE, EXPR_NOISE_LEN, 1, (16), (1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, several_search) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_several_search");
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 2, (5, 6), (0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 4, (5, 6, 15, 16),
|
||||||
|
(0, 1, 0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, first_char) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_first_char");
|
||||||
|
SEARCH_CHAR_SET(EXPR_UNIFORM_1_A, EXPR_UNIFORM_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array[0], buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, last_char) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_last_char");
|
||||||
|
SEARCH_CHAR_SET(EXPR_UNIFORM_1_B, EXPR_UNIFORM_LEN, 1, (5), (1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array[1], buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, empty_buff) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_empty_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_CHAR_SET("", 0, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_char_set_search", character_array, buffer);
|
||||||
|
hs_free_char_set_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(char_set_search, nullptr_pattern) {
|
||||||
|
const hs_char_set_compiled_pattern_t *database = nullptr;
|
||||||
|
context_t context;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
const char *buffer;
|
||||||
|
hs_error_t ret;
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_CHAR_SET(EXPR_NOISE_5, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
},
|
||||||
|
"called with nullptr database");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, nullptr_buffer) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_nullptr_buffer");
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_CHAR_SET(nullptr, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
},
|
||||||
|
"called with nullptr buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(char_set_search, nullptr_callback) {
|
||||||
|
COMPILE_CHAR_SET(CHAR_SET_AB, 2);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_char_set_search_nullptr_callback");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 2;
|
||||||
|
size_t expected_start_array[expected_match] = {5, 6};
|
||||||
|
size_t expected_end_array[expected_match] = {5, 6};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
expected_end_array[i] += 1;
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
hs_char_set_search(database, buffer, buffer_len, nullptr, &context);
|
||||||
|
},
|
||||||
|
"called with nullptr callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
210
unit/direct_API/common.h
Normal file
210
unit/direct_API/common.h
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COMMON_H
|
||||||
|
#define COMMON_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
#include "hs_common.h"
|
||||||
|
#include "hs_compile.h"
|
||||||
|
#include "hs_runtime.h"
|
||||||
|
#include "hs_direct_search.h"
|
||||||
|
#include "hs_direct_search_types.h"
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define PATTERN_0_CHAR ""
|
||||||
|
#define PATTERN_1_CHAR "a"
|
||||||
|
#define PATTERN_1_CHAR_NULL "\0"
|
||||||
|
#define PATTERN_2_CHAR "aB"
|
||||||
|
#define PATTERN_2_WITH_NULL "a\0"
|
||||||
|
#define PATTERN_3_CHAR "aBc"
|
||||||
|
#define PATTERN_5_CHAR "aBcde"
|
||||||
|
#define PATTERN_5_WITH_NULL "a\0Bcd"
|
||||||
|
#define PATTERN_8_CHAR "aBcdeoAb"
|
||||||
|
#define PATTERN_10_CHAR "aBcdeoAbCD"
|
||||||
|
#define PATTERN_25_CHAR "aBcdeoAbCDumefnvqmuz,crhUq"
|
||||||
|
|
||||||
|
#define CHAR_SET_NULL "\0"
|
||||||
|
#define CHAR_SET_A "aaAA"
|
||||||
|
#define CHAR_SET_AB "aB"
|
||||||
|
#define CHAR_SET_ABCDE "aBcde"
|
||||||
|
|
||||||
|
#define PAIR_SET_ABCD "aBcd"
|
||||||
|
#define PAIR_SET_A_NULL_BC "a\0Bc"
|
||||||
|
#define PAIR_SET_AB_DUPLICATE "aBaB"
|
||||||
|
#define PAIR_SET_LONG_PATTERN_AB "u0u1u2u3u4u5u6u7aB"
|
||||||
|
|
||||||
|
#define PATTERN_ARRAY_CONTAIN_EMPTY_0 {""}
|
||||||
|
#define PATTERN_ARRAY_SINGLE_CHAR_PAT_1 {"a"}
|
||||||
|
#define PATTERN_ARRAY_SINGLE_PAT_5 {"aBcde"}
|
||||||
|
#define PATTERN_ARRAY_GENERAL_5_5 {"aBcde","fghij"}
|
||||||
|
#define PATTERN_ARRAY_GENERAL_5_DUPLICATE {"aBcde","aBcde"}
|
||||||
|
#define PATTERN_ARRAY_LONG_10_10 {"aBcdeoAbCD","muz,crhUqu"}
|
||||||
|
#define PATTERN_ARRAY_CONTAIN_NULLPTR_5_0 {"aBcde",nullptr}
|
||||||
|
#define PATTERN_ARRAY_CONTAIN_EMPTY_0 {""}
|
||||||
|
#define PATTERN_ARRAY_WITH_NULL_5_5 {"a\0Bcd","aBcde"}
|
||||||
|
#define PATTERN_ARRAY_OVERLAP_5_8 {"aBcde","cdeoAbCD"}
|
||||||
|
#define PATTERN_ARRAY_NULLPTR ((char**)nullptr)
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define EXPR_NOISE_LEN 32
|
||||||
|
#define EXPR_NOISE "zmeh vnMezr,xbzumefnvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_0 "aBcdeoAbCDr,xbzumefnvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_5 "zmeh aBcdeoAbCDumefnvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_5_NULL "zmeh a\0Bcdr,xbzumefnvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_5_15 "zmeh aBcdeoAbCDaBcdeoAbCD,crhUqu"
|
||||||
|
#define EXPR_NOISE_5_15_BAD_CASE "zmeh AbcdeoAbCDABcdeoAbCD,crhUqu"
|
||||||
|
#define EXPR_NOISE_MIX "zmeh fgcder,xbzumefnvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_PAT2_5 "zmeh fghijr,xbzumefnvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_DUO_5_15 "zmeh aBcdeoAbCDfghijvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_SHORT_ONLY_5 "zmeh aBcdeoAbHHumefnvqmuz,crhUqu"
|
||||||
|
#define EXPR_NOISE_5_AB "zmeh aBMezr,xbzumefnvqmuz,crhUqu"
|
||||||
|
|
||||||
|
#define EXPR_NOISE_A_END_31 "zmeh vnMezr,xbzumefnvqmuz,crhUqa"
|
||||||
|
#define EXPR_NOISE_AB_END_30 "zmeh vnMezr,xbzumefnvqmuz,crhUaB"
|
||||||
|
#define EXPR_NOISE_ABCDE_END_27 "zmeh vnMezr,xbzumefnvqmuz,caBcde"
|
||||||
|
#define EXPR_NOISE_ABCDEOABCD_END_22 "zmeh vnMezr,xbzumefnvqaBcdeoAbCD"
|
||||||
|
|
||||||
|
#define EXPR_UNIFORM_LEN 32
|
||||||
|
#define EXPR_UNIFORM "uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu"
|
||||||
|
#define EXPR_UNIFORM_1_A "uuuuuauuuuuuuuuuuuuuuuuuuuuuuuuu"
|
||||||
|
#define EXPR_UNIFORM_1_B "uuuuuBuuuuuuuuuuuuuuuuuuuuuuuuuu"
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define BRACED_INIT_LIST(...) {__VA_ARGS__}
|
||||||
|
|
||||||
|
#define EXPECT_COMPILE_SUCCESS(func_name) \
|
||||||
|
EXPECT_EQ(compile_ret, HS_SUCCESS) \
|
||||||
|
<< "Fail to build the pattern in " << (func_name) << "\n"; \
|
||||||
|
EXPECT_NE(database, nullptr) \
|
||||||
|
<< "Compilation returned nullptr database " << (func_name) << "\n";
|
||||||
|
|
||||||
|
#define EXPECT_COMPILE_FAILURE(func_name) \
|
||||||
|
EXPECT_NE(compile_ret, HS_SUCCESS) \
|
||||||
|
<< "Pattern built fine when error was expected in " << (func_name) \
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
#define ASSERT_COMPILE_SUCCESS(func_name) \
|
||||||
|
ASSERT_EQ(compile_ret, HS_SUCCESS) \
|
||||||
|
<< "Fail to build the pattern in " << (func_name) << "\n"; \
|
||||||
|
ASSERT_NE(database, nullptr) \
|
||||||
|
<< "Compilation returned nullptr database " << (func_name) << "\n";
|
||||||
|
|
||||||
|
#define ASSERT_COMPILE_FAILURE(func_name) \
|
||||||
|
ASSERT_NE(compile_ret, HS_SUCCESS) \
|
||||||
|
<< "Pattern built fine when error was expected in " << (func_name) \
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
#define EXPECT_SEARCH_SUCCESS(search_func_name, pattern, buffer) \
|
||||||
|
EXPECT_EQ(HS_SUCCESS, ret) \
|
||||||
|
<< (search_func_name) << ", pattern: " << (pattern) << ", buffer: \"" \
|
||||||
|
<< (buffer) << "\"\n Search failed"; \
|
||||||
|
EXPECT_EQ(context.array_size, context.number_matched) \
|
||||||
|
<< (search_func_name) << ", pattern: " << (pattern) << ", buffer: \"" \
|
||||||
|
<< (buffer) << "\"\n Missed some matches.\n"; \
|
||||||
|
EXPECT_LE(0, context.number_wrong) \
|
||||||
|
<< (search_func_name) << ", pattern: " << (pattern) << ", buffer: \"" \
|
||||||
|
<< (buffer) << "\"\n Unexpected matches.\n";
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct callback_context {
|
||||||
|
/* array of indices in the string where we expect match to start*/
|
||||||
|
size_t *expected_start_array;
|
||||||
|
/* array of indices in the string where we expect match to end*/
|
||||||
|
size_t *expected_end_array;
|
||||||
|
/* array of pattern ID we expect match to be reported, in order */
|
||||||
|
size_t *expected_id_array;
|
||||||
|
size_t array_size;
|
||||||
|
/* counter of matches happening at a position in expected_array */
|
||||||
|
size_t number_matched;
|
||||||
|
/* counter of matches happening at a position NOT in expected_array */
|
||||||
|
size_t number_wrong;
|
||||||
|
} context_t;
|
||||||
|
|
||||||
|
static
|
||||||
|
int callback(unsigned int id, unsigned long long start,
|
||||||
|
unsigned long long end_offset, unsigned int flags,
|
||||||
|
void *raw_context) {
|
||||||
|
(void)flags;
|
||||||
|
context_t *context = reinterpret_cast<context_t*>(raw_context);
|
||||||
|
bool matched = false;
|
||||||
|
// Check if the match is expected
|
||||||
|
for (size_t i = 0; i < context->array_size; i++) {
|
||||||
|
if (end_offset == context->expected_end_array[i] &&
|
||||||
|
start == context->expected_start_array[i] &&
|
||||||
|
id == context->expected_id_array[i]) {
|
||||||
|
matched = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Tally the right counter whether the match was expected or not
|
||||||
|
if (matched) {
|
||||||
|
context->number_matched += 1;
|
||||||
|
// printf("match at index %llu\n", end_offset);
|
||||||
|
} else {
|
||||||
|
context->number_wrong += 1;
|
||||||
|
// printf("unplanned match at index %llu\n", end_offset);
|
||||||
|
}
|
||||||
|
return CB_CONTINUE_MATCHING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unordered_set<void *> alloced_mem;
|
||||||
|
|
||||||
|
static void* test_malloc(size_t size) {
|
||||||
|
void * mem = malloc(size);
|
||||||
|
alloced_mem.insert(mem);
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_free(void *ptr) {
|
||||||
|
size_t erased_count = alloced_mem.erase(ptr);
|
||||||
|
if(erased_count == 1) {
|
||||||
|
free(ptr);
|
||||||
|
} else {
|
||||||
|
printf("all currently allocated memory:\n");
|
||||||
|
for (const void *elem : alloced_mem)
|
||||||
|
printf("%p ", elem);
|
||||||
|
printf("\nTrying to free: %p\n", ptr);
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SETUP_MEM_LEAK_TEST() hs_set_allocator(test_malloc, test_free);
|
||||||
|
#define UNSET_MEM_LEAK_TEST() hs_set_allocator(nullptr, nullptr);
|
||||||
|
#define EXPECT_MEMORY_CLEAN() \
|
||||||
|
EXPECT_TRUE(alloced_mem.empty()); \
|
||||||
|
alloced_mem.clear();
|
||||||
|
|
||||||
|
#endif // COMMON_H
|
394
unit/direct_API/long_literal.cpp
Normal file
394
unit/direct_API/long_literal.cpp
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "common.h"
|
||||||
|
|
||||||
|
#include "fdr/fdr_internal.h"
|
||||||
|
|
||||||
|
#define COMPILE_LONG_LITERAL(in_pattern, in_pattern_len) \
|
||||||
|
size_t pattern_len = (in_pattern_len); \
|
||||||
|
const char *pattern = (in_pattern); \
|
||||||
|
hs_long_literal_compiled_pattern_t *database = nullptr; \
|
||||||
|
hs_error_t compile_ret = \
|
||||||
|
hs_compile_long_literal_search(pattern, pattern_len, &database); \
|
||||||
|
hs_error_t ret = 0; \
|
||||||
|
(void)ret; /* suppress a cppcheck warning when SEARCH is not called */ \
|
||||||
|
const char *buffer = nullptr; \
|
||||||
|
(void)buffer; \
|
||||||
|
context_t context = {}; \
|
||||||
|
(void) context;
|
||||||
|
|
||||||
|
// expected match array here is the index of the start of match.
|
||||||
|
#define SEARCH_LONG_LITERAL(in_buffer, in_buffer_len, in_expected_match, \
|
||||||
|
in_expected_start_array) \
|
||||||
|
{ \
|
||||||
|
buffer = (in_buffer); \
|
||||||
|
const size_t buffer_len = (in_buffer_len); \
|
||||||
|
const size_t expected_match = (in_expected_match); \
|
||||||
|
size_t expected_start_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_end_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_id_array[expected_match]; \
|
||||||
|
for (size_t i = 0; i < expected_match; i++) { \
|
||||||
|
expected_end_array[i] += pattern_len; \
|
||||||
|
expected_id_array[i] = 0; \
|
||||||
|
} \
|
||||||
|
context.expected_start_array = expected_start_array; \
|
||||||
|
context.expected_end_array = expected_end_array; \
|
||||||
|
context.expected_id_array = expected_id_array; \
|
||||||
|
context.array_size = expected_match; \
|
||||||
|
context.number_matched = 0; \
|
||||||
|
context.number_wrong = 0; \
|
||||||
|
\
|
||||||
|
ret = hs_long_literal_search(database, buffer, buffer_len, callback, \
|
||||||
|
&context); \
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(HS_SHORT_PATTERN_THRESHOLD == 8,
|
||||||
|
"changing the threshold for short/long literal require changing "
|
||||||
|
"the tests to still test the threshold behavior");
|
||||||
|
|
||||||
|
// ------------------------free tests-------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_free_long_literal_pattern
|
||||||
|
nullptr
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(long_literal_free, nullptr) {
|
||||||
|
hs_long_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_free, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
combined_fdr_database *clear_database =
|
||||||
|
reinterpret_cast<combined_fdr_database *>(
|
||||||
|
test_malloc(sizeof(combined_fdr_database)));
|
||||||
|
|
||||||
|
hs_long_literal_compiled_pattern_t *database =
|
||||||
|
reinterpret_cast<hs_long_literal_compiled_pattern_t*>(clear_database);
|
||||||
|
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------compile tests----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_compile_long_literal_search
|
||||||
|
<=8 char
|
||||||
|
general (>8 char)
|
||||||
|
valid pattern including null char
|
||||||
|
|
||||||
|
empty expression
|
||||||
|
nullptr expression
|
||||||
|
nullptr output
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(long_literal_compile, short) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_long_literal_general");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_compile, general) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_long_literal_general");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_compile, null_char) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_5_WITH_NULL, 5);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_long_literal_null_char");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(long_literal_compile, empty_pattern) {
|
||||||
|
hs_long_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
hs_compile_long_literal_search(PATTERN_0_CHAR, 0, &database),
|
||||||
|
"called with an empty pattern");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_compile, nullptr_pattern) {
|
||||||
|
hs_long_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_long_literal_search(nullptr, 5, &database),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_compile, nullptr_database) {
|
||||||
|
EXPECT_DEATH(hs_compile_long_literal_search(PATTERN_5_CHAR, 5, nullptr),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------search tests-----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_long_literal_search
|
||||||
|
short pattern
|
||||||
|
positive match
|
||||||
|
negative match
|
||||||
|
general pattern
|
||||||
|
general pattern but the buffer only have the short part of it
|
||||||
|
extra long pattern (vectorized confirm)
|
||||||
|
match at start
|
||||||
|
match middle (general)
|
||||||
|
match index 15 (cross over vector)
|
||||||
|
match at end
|
||||||
|
match past end (a few char ok, then end, so missing some chars)
|
||||||
|
bad caseness
|
||||||
|
search several times
|
||||||
|
single char pattern
|
||||||
|
general match
|
||||||
|
match at end
|
||||||
|
no match
|
||||||
|
buffer containing null char
|
||||||
|
pattern with null char
|
||||||
|
general pattern (no null char searched for)
|
||||||
|
buff size 0
|
||||||
|
nullptr pattern
|
||||||
|
nullptr buffer
|
||||||
|
nullptr callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(long_literal_search, short_positive) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_general");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, short_negative) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_general");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, short_but_negative_long) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_short_but_negative_long");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_SHORT_ONLY_5, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, start) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_start");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_0, EXPR_NOISE_LEN, 1, (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_general");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, extra_long) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_25_CHAR, 25);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_extra_long");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, cross_vector) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_cross_vector");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, end) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_end");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_ABCDEOABCD_END_22, EXPR_NOISE_LEN, 1, (22));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, past_end) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_past_end");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_ABCDEOABCD_END_22, EXPR_NOISE_LEN - 3, 0,
|
||||||
|
());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, bad_case) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_bad_case");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5_15_BAD_CASE, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, several_search) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_several_search");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, single_char) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_1_CHAR, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_single_char");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, single_char_end) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_1_CHAR, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_single_char_end");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN - 1, 1, (30));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, single_char_no_match) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_1_CHAR, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_single_char_no_match");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, null_char_buff_and_pattern) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_5_WITH_NULL, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS(
|
||||||
|
"test_long_literal_search_null_char_buff_and_pattern");
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, null_char_buff) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_null_char_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, empty_buff) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_empty_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_LONG_LITERAL("", 0, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_long_literal_search", pattern, buffer);
|
||||||
|
hs_free_long_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(long_literal_search, nullptr_pattern) {
|
||||||
|
const hs_long_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
context_t context;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
const char *buffer;
|
||||||
|
hs_error_t ret;
|
||||||
|
size_t pattern_len = 5;
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_LONG_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr database");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, nullptr_buffer) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_nullptr_buffer");
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_LONG_LITERAL(nullptr, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(long_literal_search, nullptr_callback) {
|
||||||
|
COMPILE_LONG_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_long_literal_search_nullptr_callback");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 1;
|
||||||
|
size_t expected_start_array[expected_match] = {5};
|
||||||
|
size_t expected_end_array[expected_match] = {5};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
expected_end_array[i] += pattern_len;
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
hs_long_literal_search(database, buffer, buffer_len, nullptr,
|
||||||
|
&context);
|
||||||
|
},
|
||||||
|
"called with nullptr callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
36
unit/direct_API/main.cpp
Normal file
36
unit/direct_API/main.cpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "gtest/gtest.h"
|
||||||
|
|
||||||
|
// Driver: run all the tests (defined in other source files in this directory)
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
515
unit/direct_API/multi_literal.cpp
Normal file
515
unit/direct_API/multi_literal.cpp
Normal file
@ -0,0 +1,515 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "common.h"
|
||||||
|
|
||||||
|
#include "fdr/fdr_internal.h"
|
||||||
|
|
||||||
|
#define COMPILE_MULTI_LITERAL(in_pattern, in_pattern_count, in_pattern_len) \
|
||||||
|
const size_t pattern_count = (in_pattern_count); \
|
||||||
|
size_t pattern_len[pattern_count] = BRACED_INIT_LIST in_pattern_len; \
|
||||||
|
const char *pattern_storage[] = in_pattern; \
|
||||||
|
const char **pattern = pattern_storage; \
|
||||||
|
hs_multi_literal_compiled_pattern_t *database = nullptr; \
|
||||||
|
hs_error_t compile_ret = hs_compile_multi_literal_search( \
|
||||||
|
pattern, pattern_count, pattern_len, &database); \
|
||||||
|
hs_error_t ret = 0; \
|
||||||
|
(void)ret; /* suppress a cppcheck warning when SEARCH is not called */ \
|
||||||
|
const char *buffer = nullptr; \
|
||||||
|
(void)buffer; \
|
||||||
|
context_t context = {}; \
|
||||||
|
(void) context;
|
||||||
|
|
||||||
|
// expected match array here is the index of the start of match, assuming it
|
||||||
|
// match a pattern with the same length as pattern 0
|
||||||
|
#define SEARCH_MULTI_LITERAL(in_buffer, in_buffer_len, in_expected_match, \
|
||||||
|
in_expected_start_array, in_expected_id_array) \
|
||||||
|
{ \
|
||||||
|
buffer = (in_buffer); \
|
||||||
|
const size_t buffer_len = (in_buffer_len); \
|
||||||
|
const size_t expected_match = (in_expected_match); \
|
||||||
|
size_t expected_start_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_end_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_id_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_id_array; \
|
||||||
|
for (size_t i = 0; i < expected_match; i++) { \
|
||||||
|
expected_end_array[i] += pattern_len[0]; \
|
||||||
|
} \
|
||||||
|
context.expected_start_array = expected_start_array; \
|
||||||
|
context.expected_end_array = expected_end_array; \
|
||||||
|
context.expected_id_array = expected_id_array; \
|
||||||
|
context.array_size = expected_match; \
|
||||||
|
context.number_matched = 0; \
|
||||||
|
context.number_wrong = 0; \
|
||||||
|
\
|
||||||
|
ret = hs_multi_literal_search(database, buffer, buffer_len, callback, \
|
||||||
|
&context); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------free tests-------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_free_multi_literal_pattern
|
||||||
|
nullptr
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(multi_literal_free, nullptr) {
|
||||||
|
hs_multi_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_free, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
combined_fdr_database *clear_database =
|
||||||
|
reinterpret_cast<combined_fdr_database *>(
|
||||||
|
test_malloc(sizeof(combined_fdr_database)));
|
||||||
|
|
||||||
|
hs_multi_literal_compiled_pattern_t *database =
|
||||||
|
reinterpret_cast<hs_multi_literal_compiled_pattern_t*>(clear_database);
|
||||||
|
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------compile tests----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_compile_multi_literal_search
|
||||||
|
single expression
|
||||||
|
single char expression
|
||||||
|
general (several expressions)
|
||||||
|
pattern duplicate
|
||||||
|
valid pattern including null char
|
||||||
|
overlaping patterns (eg, "abba" and "bb")
|
||||||
|
|
||||||
|
no expressions
|
||||||
|
empty expression
|
||||||
|
nullptr expression array
|
||||||
|
one of the expression is nullptr
|
||||||
|
nullptr output
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, single_pattern) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_SINGLE_PAT_5, 1, (5));
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_multi_literal_single_pattern");
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, single_pattern_single_char) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_SINGLE_CHAR_PAT_1, 1, (1));
|
||||||
|
EXPECT_COMPILE_SUCCESS(
|
||||||
|
"test_compile_multi_literal_single_pattern_single_char");
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, general) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_multi_literal_general");
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, duplicate) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_DUPLICATE, 2, (5, 5));
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_multi_literal_duplicate");
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, with_null_char) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_WITH_NULL_5_5, 2, (5, 5));
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_multi_literal_with_null_char");
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, overlapping_patterns) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_OVERLAP_5_8, 2, (5, 8));
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_multi_literal_overlapping_patterns");
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, no_expression) {
|
||||||
|
const size_t pattern_count = 0;
|
||||||
|
const char *pattern_storage[] = PATTERN_ARRAY_GENERAL_5_5;
|
||||||
|
const char **pattern = pattern_storage;
|
||||||
|
hs_multi_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
size_t pattern_len[2];
|
||||||
|
pattern_len[0] = 5;
|
||||||
|
pattern_len[1] = 5;
|
||||||
|
hs_compile_multi_literal_search(pattern, pattern_count, pattern_len,
|
||||||
|
&database);
|
||||||
|
},
|
||||||
|
"called with no pattern");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, empty_expression) {
|
||||||
|
const size_t pattern_count = 1;
|
||||||
|
const size_t pattern_len[pattern_count] = {0};
|
||||||
|
const char *pattern_storage[] = PATTERN_ARRAY_CONTAIN_EMPTY_0;
|
||||||
|
const char **pattern = pattern_storage;
|
||||||
|
hs_multi_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_multi_literal_search(pattern, pattern_count,
|
||||||
|
pattern_len, &database),
|
||||||
|
"called with an empty pattern");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, nullptr_pattern_array) {
|
||||||
|
const size_t pattern_count = 1;
|
||||||
|
const size_t pattern_len[pattern_count] = {5};
|
||||||
|
const char **pattern = nullptr;
|
||||||
|
hs_multi_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_multi_literal_search(pattern, pattern_count,
|
||||||
|
pattern_len, &database),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, nullptr_pattern_in_array) {
|
||||||
|
const size_t pattern_count = 2;
|
||||||
|
const size_t pattern_len[pattern_count] = {5, 5};
|
||||||
|
const char *pattern_storage[] = PATTERN_ARRAY_CONTAIN_NULLPTR_5_0;
|
||||||
|
const char **pattern = pattern_storage;
|
||||||
|
hs_multi_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_multi_literal_search(pattern, pattern_count,
|
||||||
|
pattern_len, &database),
|
||||||
|
"called with an empty pattern");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_compile, nullptr_database) {
|
||||||
|
const size_t pattern_count = 2;
|
||||||
|
const size_t pattern_len[pattern_count] = {5, 5};
|
||||||
|
const char *pattern_storage[] = PATTERN_ARRAY_GENERAL_5_5;
|
||||||
|
const char **pattern = pattern_storage;
|
||||||
|
EXPECT_DEATH(hs_compile_multi_literal_search(pattern, pattern_count,
|
||||||
|
pattern_len, nullptr),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------search tests-----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_multi_literal_search
|
||||||
|
general pattern
|
||||||
|
match at start
|
||||||
|
match middle (general)
|
||||||
|
match index 15 (cross over vector)
|
||||||
|
match at end
|
||||||
|
match past end (a few char ok, then end, so missing some chars)
|
||||||
|
match long patterns
|
||||||
|
long pattern but the buffer only have the short part of it
|
||||||
|
bad caseness
|
||||||
|
search several times
|
||||||
|
match first pattern
|
||||||
|
match last pattern
|
||||||
|
match several pattern in the same search
|
||||||
|
match overlapping patterns
|
||||||
|
pattern mix (start with pattern A, finish with pattern B. Expect no
|
||||||
|
match)
|
||||||
|
match a pattern duplicate
|
||||||
|
single char pattern
|
||||||
|
general match
|
||||||
|
match at end
|
||||||
|
no match
|
||||||
|
buffer containing null char
|
||||||
|
pattern with null char
|
||||||
|
general pattern (no null char searched for)
|
||||||
|
buff size 0
|
||||||
|
nullptr pattern
|
||||||
|
nullptr buffer
|
||||||
|
nullptr callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(multi_literal_search, start) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_start");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_0, EXPR_NOISE_LEN, 1, (0), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_general");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, cross_vector) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_cross_vector");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15), (0, 0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, end) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_end");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_ABCDE_END_27, EXPR_NOISE_LEN, 1, (27), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, past_end) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_past_end");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_ABCDE_END_27, EXPR_NOISE_LEN - 3, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, long_pattern) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_LONG_10_10, 2, (10, 10));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_long_pattern");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 2, (5, 22), (0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, short_but_negative_long) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_LONG_10_10, 2, (10, 10));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_short_but_negative_long");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_SHORT_ONLY_5, EXPR_NOISE_LEN, 1, (22), (1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[1], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, bad_case) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_bad_case");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5_15_BAD_CASE, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, several_search) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_several_search");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15), (0, 0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, first_pattern) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_first_pattern");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, last_pattern) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_last_pattern");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_PAT2_5, EXPR_NOISE_LEN, 1, (5), (1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[1], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, multi_pattern) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_multi_pattern");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_DUO_5_15, EXPR_NOISE_LEN, 2, (5, 15),
|
||||||
|
(0, 1));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, overlap) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_OVERLAP_5_8, 2, (5, 8));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_overlap");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 2;
|
||||||
|
size_t expected_start_array[expected_match] = {5, 7};
|
||||||
|
size_t expected_end_array[expected_match] = {5, 7};
|
||||||
|
size_t expected_id_array[expected_match] = {0, 1};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
// we need the length of the second pattern, hence not using the macro
|
||||||
|
expected_end_array[i] += pattern_len[i];
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.expected_id_array = expected_id_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
ret = hs_multi_literal_search(database, buffer, buffer_len,
|
||||||
|
callback, &context);
|
||||||
|
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, pattern_mix) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_pattern_mix");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_MIX, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, duplicate) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_DUPLICATE, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_duplicate");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, single_char) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_SINGLE_CHAR_PAT_1, 1, (1));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_single_char");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15), (0, 0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, single_char_end) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_SINGLE_CHAR_PAT_1, 1, (1));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_single_char_end");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN - 1, 1, (30),
|
||||||
|
(0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, single_char_no_match) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_SINGLE_CHAR_PAT_1, 1, (1));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_single_char_no_match");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, null_char_buff_and_pattern) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_WITH_NULL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS(
|
||||||
|
"test_multi_literal_search_null_char_buff_and_pattern");
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (5), (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, null_char_buff) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_null_char_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, empty_buff) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_empty_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_MULTI_LITERAL("", 0, 0, (), ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_multi_literal_search", pattern[0], buffer);
|
||||||
|
hs_free_multi_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(multi_literal_search, nullptr_pattern) {
|
||||||
|
const hs_multi_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
context_t context;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
const char *buffer;
|
||||||
|
hs_error_t ret;
|
||||||
|
size_t pattern_len[2];
|
||||||
|
pattern_len[0] = 5;
|
||||||
|
pattern_len[1] = 5;
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_MULTI_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
},
|
||||||
|
"called with nullptr database");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, nullptr_buffer) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_nullptr_buffer");
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_MULTI_LITERAL(nullptr, EXPR_NOISE_LEN, 0, (), ());
|
||||||
|
},
|
||||||
|
"called with nullptr buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(multi_literal_search, nullptr_callback) {
|
||||||
|
COMPILE_MULTI_LITERAL(PATTERN_ARRAY_GENERAL_5_5, 2, (5, 5));
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_multi_literal_search_nullptr_callback");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 1;
|
||||||
|
size_t expected_start_array[expected_match] = {5};
|
||||||
|
size_t expected_end_array[expected_match] = {5};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
expected_end_array[i] += pattern_len[0];
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
hs_multi_literal_search(database, buffer, buffer_len, nullptr,
|
||||||
|
&context);
|
||||||
|
},
|
||||||
|
"called with nullptr callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
377
unit/direct_API/short_literal.cpp
Normal file
377
unit/direct_API/short_literal.cpp
Normal file
@ -0,0 +1,377 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "direct_API/common.h"
|
||||||
|
|
||||||
|
#include "hwlm/noodle_internal.h"
|
||||||
|
|
||||||
|
#define COMPILE_SHORT_LITERAL(in_pattern, in_pattern_len) \
|
||||||
|
size_t pattern_len = (in_pattern_len); \
|
||||||
|
const char *pattern = (in_pattern); \
|
||||||
|
hs_short_literal_compiled_pattern_t *database = nullptr; \
|
||||||
|
hs_error_t compile_ret = \
|
||||||
|
hs_compile_short_literal_search(pattern, pattern_len, &database); \
|
||||||
|
hs_error_t ret = 0; \
|
||||||
|
(void)ret; /* suppress a cppcheck warning when SEARCH is not called */ \
|
||||||
|
const char *buffer = nullptr; \
|
||||||
|
(void)buffer; \
|
||||||
|
context_t context = {}; \
|
||||||
|
(void) context;
|
||||||
|
|
||||||
|
// expected match array here is the index of the start of match.
|
||||||
|
#define SEARCH_SHORT_LITERAL(in_buffer, in_buffer_len, in_expected_match, \
|
||||||
|
in_expected_start_array) \
|
||||||
|
{ \
|
||||||
|
buffer = (in_buffer); \
|
||||||
|
const size_t buffer_len = (in_buffer_len); \
|
||||||
|
const size_t expected_match = (in_expected_match); \
|
||||||
|
size_t expected_start_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_end_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_id_array[expected_match]; \
|
||||||
|
for (size_t i = 0; i < expected_match; i++) { \
|
||||||
|
expected_end_array[i] += pattern_len; \
|
||||||
|
expected_id_array[i] = 0; \
|
||||||
|
} \
|
||||||
|
context.expected_start_array = expected_start_array; \
|
||||||
|
context.expected_end_array = expected_end_array; \
|
||||||
|
context.expected_id_array = expected_id_array; \
|
||||||
|
context.array_size = expected_match; \
|
||||||
|
context.number_matched = 0; \
|
||||||
|
context.number_wrong = 0; \
|
||||||
|
\
|
||||||
|
ret = hs_short_literal_search(database, buffer, buffer_len, callback, \
|
||||||
|
&context); \
|
||||||
|
}
|
||||||
|
|
||||||
|
static_assert(HS_SHORT_PATTERN_THRESHOLD == 8,
|
||||||
|
"changing the threshold for short/long literal require changing "
|
||||||
|
"the tests to still test the threshold behavior");
|
||||||
|
|
||||||
|
// ------------------------free tests-------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_free_short_literal_pattern
|
||||||
|
nullptr
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(short_literal_free, nullptr) {
|
||||||
|
hs_short_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_free, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
noodTable *clear_database =
|
||||||
|
reinterpret_cast<noodTable *>(test_malloc(sizeof(noodTable)));
|
||||||
|
hs_short_literal_compiled_pattern_t *database =
|
||||||
|
reinterpret_cast<hs_short_literal_compiled_pattern_t *>(
|
||||||
|
clear_database);
|
||||||
|
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------compile tests----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_compile_short_literal_search
|
||||||
|
single char
|
||||||
|
general
|
||||||
|
8 char
|
||||||
|
>8 char
|
||||||
|
valid pattern including null char
|
||||||
|
empty expression
|
||||||
|
nullptr expression
|
||||||
|
nullptr output
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(short_literal_compile, single_char) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_1_CHAR, 1);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_short_literal_single_char");
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_compile, general) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_short_literal_general");
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_compile, max_length) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_8_CHAR, 8);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_short_literal_max_len");
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_compile, too_long) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_10_CHAR, 10);
|
||||||
|
EXPECT_COMPILE_FAILURE("test_compile_short_literal_too_long");
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_compile, null_char) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_WITH_NULL, 5);
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_short_literal_null_char");
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(short_literal_compile, empty_pattern) {
|
||||||
|
hs_short_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
hs_compile_short_literal_search(PATTERN_0_CHAR, 0, &database),
|
||||||
|
"called with an empty pattern");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_compile, nullptr_pattern) {
|
||||||
|
hs_short_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_short_literal_search(nullptr, 5, &database),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_compile, nullptr_database) {
|
||||||
|
EXPECT_DEATH(hs_compile_short_literal_search(PATTERN_5_CHAR, 5, nullptr),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------search tests-----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_short_literal_search
|
||||||
|
general pattern
|
||||||
|
match at start
|
||||||
|
match middle (general)
|
||||||
|
match index 15 (noodle cross over vector)
|
||||||
|
match at end
|
||||||
|
match the full pattern, not just the first pair
|
||||||
|
match past end (2 char ok, then end, so missing some chars)
|
||||||
|
bad caseness
|
||||||
|
search several times
|
||||||
|
single char pattern
|
||||||
|
general match
|
||||||
|
match at end
|
||||||
|
no match
|
||||||
|
buffer containing null char
|
||||||
|
pattern with null char
|
||||||
|
general pattern
|
||||||
|
buff size 0
|
||||||
|
nullptr pattern
|
||||||
|
nullptr buffer
|
||||||
|
nullptr callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(short_literal_search, start) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_start");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_0, EXPR_NOISE_LEN, 1, (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_general");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, cross_vector) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_cross_vector");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, end) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_end");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_ABCDE_END_27, EXPR_NOISE_LEN, 1, (27));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, past_end) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_past_end");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_ABCDE_END_27, EXPR_NOISE_LEN - 3, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, short_no_match) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_short_no_match");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5_AB, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, bad_case) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_bad_case");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5_15_BAD_CASE, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, several_search) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_several_search");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
// cppcheck-suppress redundantAssignment
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, single_char) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_1_CHAR, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_single_char");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, single_char_end) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_1_CHAR, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_single_char_end");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN - 1, 1, (30));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, single_char_no_match) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_1_CHAR, 1);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_single_char_no_match");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, null_char_buff_and_pattern) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_WITH_NULL, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS(
|
||||||
|
"test_short_literal_search_null_char_buff_and_pattern");
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, null_char_buff) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_null_char_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, empty_buff) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_empty_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SHORT_LITERAL("", 0, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_short_literal_search", pattern, buffer);
|
||||||
|
hs_free_short_literal_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(short_literal_search, nullptr_pattern) {
|
||||||
|
const hs_short_literal_compiled_pattern_t *database = nullptr;
|
||||||
|
context_t context;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
const char *buffer;
|
||||||
|
hs_error_t ret;
|
||||||
|
size_t pattern_len = 5;
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_SHORT_LITERAL(EXPR_NOISE_5, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr database");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, nullptr_buffer) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_nullptr_buffer");
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_SHORT_LITERAL(nullptr, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(short_literal_search, nullptr_callback) {
|
||||||
|
COMPILE_SHORT_LITERAL(PATTERN_5_CHAR, 5);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_short_literal_search_nullptr_callback");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 1;
|
||||||
|
size_t expected_start_array[expected_match] = {5};
|
||||||
|
size_t expected_end_array[expected_match] = {5};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
expected_end_array[i] += pattern_len;
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
hs_short_literal_search(database, buffer, buffer_len, nullptr,
|
||||||
|
&context);
|
||||||
|
},
|
||||||
|
"called with nullptr callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
293
unit/direct_API/single_char.cpp
Normal file
293
unit/direct_API/single_char.cpp
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "common.h"
|
||||||
|
|
||||||
|
#include "hwlm/noodle_internal.h"
|
||||||
|
|
||||||
|
#define COMPILE_SINGLE_CHAR(in_pattern) \
|
||||||
|
const char pattern = *(in_pattern); \
|
||||||
|
hs_single_char_compiled_pattern_t *database = nullptr; \
|
||||||
|
hs_error_t compile_ret = hs_compile_single_char_search(pattern, &database);\
|
||||||
|
hs_error_t ret = 0; \
|
||||||
|
(void)ret; /* suppress a cppcheck warning when SEARCH is not called */ \
|
||||||
|
const char *buffer = nullptr; \
|
||||||
|
(void)buffer; \
|
||||||
|
context_t context = {}; \
|
||||||
|
(void) context;
|
||||||
|
|
||||||
|
// expected match array here is the index of the start of match.
|
||||||
|
#define SEARCH_SINGLE_CHAR(in_buffer, in_buffer_len, in_expected_match, \
|
||||||
|
in_expected_start_array) \
|
||||||
|
{ \
|
||||||
|
buffer = (in_buffer); \
|
||||||
|
const size_t buffer_len = (in_buffer_len); \
|
||||||
|
const size_t expected_match = (in_expected_match); \
|
||||||
|
size_t expected_start_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_end_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_id_array[expected_match]; \
|
||||||
|
for (size_t i = 0; i < expected_match; i++) { \
|
||||||
|
expected_end_array[i] += 1; \
|
||||||
|
expected_id_array[i] = 0; \
|
||||||
|
} \
|
||||||
|
context.expected_start_array = expected_start_array; \
|
||||||
|
context.expected_end_array = expected_end_array; \
|
||||||
|
context.expected_id_array = expected_id_array; \
|
||||||
|
context.array_size = expected_match; \
|
||||||
|
context.number_matched = 0; \
|
||||||
|
context.number_wrong = 0; \
|
||||||
|
\
|
||||||
|
ret = hs_single_char_search(database, buffer, buffer_len, callback, \
|
||||||
|
&context); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------free tests-------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_free_single_char_pattern
|
||||||
|
nullptr
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(single_char_free, nullptr) {
|
||||||
|
hs_single_char_compiled_pattern_t *database = nullptr;
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_free, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
truffle_storage *clear_database = reinterpret_cast<truffle_storage *>(
|
||||||
|
test_malloc(sizeof(truffle_storage)));
|
||||||
|
hs_single_char_compiled_pattern_t *database =
|
||||||
|
reinterpret_cast<hs_single_char_compiled_pattern_t*>(clear_database);
|
||||||
|
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------compile tests----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_compile_single_char_search
|
||||||
|
general (1 char)
|
||||||
|
null char pattern
|
||||||
|
|
||||||
|
nullptr output
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(single_char_compile, general) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR)
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_single_char_general")
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_compile, null_char) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR)
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_single_char_null_char")
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(single_char_compile, nullptr_database) {
|
||||||
|
EXPECT_DEATH(hs_compile_single_char_search(*PATTERN_1_CHAR, nullptr),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------search tests-----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_single_char_search
|
||||||
|
general pattern
|
||||||
|
match at start
|
||||||
|
match middle (general)
|
||||||
|
match vector end
|
||||||
|
match at buffer end
|
||||||
|
match past end
|
||||||
|
bad caseness
|
||||||
|
search several times
|
||||||
|
buffer containing null char
|
||||||
|
null char pattern
|
||||||
|
general pattern
|
||||||
|
buff size 0
|
||||||
|
nullptr pattern
|
||||||
|
nullptr buffer
|
||||||
|
nullptr callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(single_char_search, start) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_start");
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_0, EXPR_NOISE_LEN, 1, (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_general");
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, end_vector) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_end_vector");
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, end) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_end");
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_A_END_31, EXPR_NOISE_LEN, 1, (31));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, past_end) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_past_end");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_A_END_31, EXPR_NOISE_LEN - 1, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, bad_case) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_bad_case");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5_15_BAD_CASE, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, several_search) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_several_search");
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, null_char_buff_and_pattern) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR_NULL);
|
||||||
|
ASSERT_COMPILE_SUCCESS(
|
||||||
|
"test_single_char_search_null_char_buff_and_pattern");
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (6));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, null_char_buff) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_null_char_buff");
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, empty_buff) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_empty_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SINGLE_CHAR("", 0, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(single_char_search, nullptr_pattern) {
|
||||||
|
const hs_single_char_compiled_pattern_t *database = nullptr;
|
||||||
|
context_t context;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
const char *buffer;
|
||||||
|
hs_error_t ret;
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_SINGLE_CHAR(EXPR_NOISE_5, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr database");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, nullptr_buffer) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_nullptr_buffer");
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_SINGLE_CHAR(nullptr, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_search, nullptr_callback) {
|
||||||
|
COMPILE_SINGLE_CHAR(PATTERN_1_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_search_nullptr_callback");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 1;
|
||||||
|
size_t expected_start_array[expected_match] = {5};
|
||||||
|
size_t expected_end_array[expected_match] = {5};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
expected_end_array[i] += 1;
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
hs_single_char_search(database, buffer, buffer_len, nullptr,
|
||||||
|
&context);
|
||||||
|
},
|
||||||
|
"called with nullptr callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
303
unit/direct_API/single_char_pair.cpp
Normal file
303
unit/direct_API/single_char_pair.cpp
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2025, Arm ltd
|
||||||
|
*
|
||||||
|
* 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 "common.h"
|
||||||
|
|
||||||
|
#include "hwlm/noodle_internal.h"
|
||||||
|
|
||||||
|
#define COMPILE_SINGLE_CHAR_PAIR(in_pattern) \
|
||||||
|
const char *pattern = (in_pattern); \
|
||||||
|
hs_single_char_pair_compiled_pattern_t *database = nullptr; \
|
||||||
|
hs_error_t compile_ret = \
|
||||||
|
hs_compile_single_char_pair_search(pattern, &database); \
|
||||||
|
hs_error_t ret = 0; \
|
||||||
|
(void)ret; /* suppress a cppcheck warning when SEARCH is not called */ \
|
||||||
|
const char *buffer = nullptr; \
|
||||||
|
(void)buffer; \
|
||||||
|
context_t context = {}; \
|
||||||
|
(void) context;
|
||||||
|
|
||||||
|
// expected match array here is the index of the start of match.
|
||||||
|
#define SEARCH_SINGLE_CHAR_PAIR(in_buffer, in_buffer_len, in_expected_match, \
|
||||||
|
in_expected_start_array) \
|
||||||
|
{ \
|
||||||
|
buffer = (in_buffer); \
|
||||||
|
const size_t buffer_len = (in_buffer_len); \
|
||||||
|
const size_t expected_match = (in_expected_match); \
|
||||||
|
size_t expected_start_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_end_array[expected_match] = \
|
||||||
|
BRACED_INIT_LIST in_expected_start_array; \
|
||||||
|
size_t expected_id_array[expected_match]; \
|
||||||
|
for (size_t i = 0; i < expected_match; i++) { \
|
||||||
|
expected_end_array[i] += 2; \
|
||||||
|
expected_id_array[i] = 0; \
|
||||||
|
} \
|
||||||
|
context.expected_start_array = expected_start_array; \
|
||||||
|
context.expected_end_array = expected_end_array; \
|
||||||
|
context.expected_id_array = expected_id_array; \
|
||||||
|
context.array_size = expected_match; \
|
||||||
|
context.number_matched = 0; \
|
||||||
|
context.number_wrong = 0; \
|
||||||
|
\
|
||||||
|
ret = hs_single_char_pair_search(database, buffer, buffer_len, \
|
||||||
|
callback, &context); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------free tests-------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_free_single_char_pair_pattern
|
||||||
|
nullptr
|
||||||
|
general
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(single_char_pair_free, nullptr) {
|
||||||
|
hs_single_char_pair_compiled_pattern_t *database = nullptr;
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_free, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
noodTable *clear_database =
|
||||||
|
reinterpret_cast<noodTable *>(test_malloc(sizeof(noodTable)));
|
||||||
|
hs_single_char_pair_compiled_pattern_t *database =
|
||||||
|
reinterpret_cast<hs_single_char_pair_compiled_pattern_t*>(
|
||||||
|
clear_database);
|
||||||
|
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------compile tests----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_compile_single_char_pair_search
|
||||||
|
general (2 char)
|
||||||
|
valid pattern including null char
|
||||||
|
|
||||||
|
nullptr expression
|
||||||
|
nullptr output
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(single_char_pair_compile, general) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR)
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_single_char_pair_general")
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_compile, with_null_char) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_WITH_NULL)
|
||||||
|
EXPECT_COMPILE_SUCCESS("test_compile_single_char_pair_with_null_char")
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(single_char_pair_compile, nullptr_pattern) {
|
||||||
|
hs_single_char_pair_compiled_pattern_t *database = nullptr;
|
||||||
|
EXPECT_DEATH(hs_compile_single_char_pair_search(nullptr, &database),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_compile, nullptr_database) {
|
||||||
|
EXPECT_DEATH(hs_compile_single_char_pair_search(PATTERN_5_CHAR, nullptr),
|
||||||
|
"called with nullptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------search tests-----------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
hs_single_char_pair_search
|
||||||
|
general pattern
|
||||||
|
match at start
|
||||||
|
match middle (general)
|
||||||
|
match index 15 (cross over vector)
|
||||||
|
match at end
|
||||||
|
match past end (1 char ok, then end, so missing one chars)
|
||||||
|
bad caseness
|
||||||
|
search several times
|
||||||
|
buffer containing null char
|
||||||
|
pattern with null char
|
||||||
|
general pattern
|
||||||
|
buff size 0
|
||||||
|
nullptr pattern
|
||||||
|
nullptr buffer
|
||||||
|
nullptr callback
|
||||||
|
*/
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, start) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_start");
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_0, EXPR_NOISE_LEN, 1, (0));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, general) {
|
||||||
|
SETUP_MEM_LEAK_TEST();
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_general");
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
EXPECT_MEMORY_CLEAN();
|
||||||
|
UNSET_MEM_LEAK_TEST();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, cross_vector) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_cross_vector");
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, end) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_end");
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN, 1, (30));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, past_end) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_past_end");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_AB_END_30, EXPR_NOISE_LEN - 1, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, bad_case) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_bad_case");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5_15_BAD_CASE, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, several_search) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_several_search");
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5_15, EXPR_NOISE_LEN, 2, (5, 15));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, null_char_buff_and_pattern) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_WITH_NULL);
|
||||||
|
ASSERT_COMPILE_SUCCESS(
|
||||||
|
"test_single_char_pair_search_null_char_buff_and_pattern");
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 1, (5));
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, null_char_buff) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_null_char_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5_NULL, EXPR_NOISE_LEN, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, empty_buff) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_empty_buff");
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR("", 0, 0, ());
|
||||||
|
EXPECT_SEARCH_SUCCESS("hs_single_char_pair_search", pattern, buffer);
|
||||||
|
hs_free_single_char_pair_pattern(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(RELEASE_BUILD)
|
||||||
|
// test asserts
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, nullptr_pattern) {
|
||||||
|
const hs_single_char_pair_compiled_pattern_t *database = nullptr;
|
||||||
|
context_t context;
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
const char *buffer;
|
||||||
|
hs_error_t ret;
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(EXPR_NOISE_5, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr database");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, nullptr_buffer) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_nullptr_buffer");
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
// cppcheck-suppress unsignedLessThanZero
|
||||||
|
// cppcheck-suppress unreadVariable
|
||||||
|
SEARCH_SINGLE_CHAR_PAIR(nullptr, EXPR_NOISE_LEN, 0, ());
|
||||||
|
},
|
||||||
|
"called with nullptr buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(single_char_pair_search, nullptr_callback) {
|
||||||
|
COMPILE_SINGLE_CHAR_PAIR(PATTERN_2_CHAR);
|
||||||
|
ASSERT_COMPILE_SUCCESS("test_single_char_pair_search_nullptr_callback");
|
||||||
|
|
||||||
|
buffer = EXPR_NOISE_5;
|
||||||
|
const size_t buffer_len = EXPR_NOISE_LEN;
|
||||||
|
const size_t expected_match = 1;
|
||||||
|
size_t expected_start_array[expected_match] = {5};
|
||||||
|
size_t expected_end_array[expected_match] = {5};
|
||||||
|
for (size_t i = 0; i < expected_match; i++) {
|
||||||
|
expected_end_array[i] += 2;
|
||||||
|
}
|
||||||
|
context.expected_start_array = expected_start_array;
|
||||||
|
context.expected_end_array = expected_end_array;
|
||||||
|
context.array_size = expected_match;
|
||||||
|
context.number_matched = 0;
|
||||||
|
context.number_wrong = 0;
|
||||||
|
|
||||||
|
EXPECT_DEATH(
|
||||||
|
{
|
||||||
|
hs_single_char_pair_search(database, buffer, buffer_len, nullptr,
|
||||||
|
&context);
|
||||||
|
},
|
||||||
|
"called with nullptr callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user