intel / intel/hyperscan

[Bug] Purely negative combination of patterns with maxOffset

Open
#373 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
5.5k
Forks
816
Avg merge
4d 21h
Merged PRs (30d)
2

Description

Hi!

I'm using pure negative logical combinations of patterns that have maxOffset value. But with small values of maxOffset (I suppose it is less 64) hyperscan doesn't call handler on hs_close_stream (or hs_reset_stream too) although scanned data doesn't have the pattern match. It seems like a bug.

The following code demonstrates this wrong case.
I compile pattern 0 "ABC" with maxOffset 63 and pattern 1 "!0". Then I scan data that doesn't contain "ABC".
But CloseHandler isn't called by hs_close_stream as I expect. If I change maxOffset to 64, everything works right and CloseHandler is called once on hs_close_stream.

```C++
#include

#include
#include
#include
#include

using namespace std::string_view_literals;

int ScanHandler(unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, void *context)
{
std::cout << "[Scan] Pattern " << id << ", offset = " << to << std::endl;
return HS_SUCCESS;
}

int CloseHandler(unsigned int id, unsigned long long from, unsigned long long to, unsigned int flags, void *context)
{
std::cout << "[Close] Pattern " << id << ", offset = " << to << std::endl;
return HS_SUCCESS;
}

int main()
{
hs_database_t* hsDatabase{nullptr};
hs_compile_error_t* compileError{nullptr};

hs_expr_ext ext0{.flags = HS_EXT_FLAG_MAX_OFFSET, .max_offset = 63};
hs_expr_ext extEmpty{};

auto hsError = hs_compile_ext_multi(
std::array{"ABC", "!0"}.data(),
std::array{0, HS_FLAG_COMBINATION}.data(),
std::array{0, 1}.data(),
std::array{&ext0, &extEmpty}.data(),
2,
HS_MODE_STREAM,
nullptr,
&hsDatabase,
&compileError);
assert(hsError == HS_SUCCESS);
hs_free_compile_error(compileError);

hs_scratch_t* hsScratch{nullptr};
hsError = hs_alloc_scratch(hsDatabase, &hsScratch);
assert(hsError == HS_SUCCESS);

hs_stream_t* hsStream{nullptr};
hsError = hs_open_stream(hsDatabase, 0, &hsStream);
assert(hsError == HS_SUCCESS);

const auto data = "ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss"sv;
hsError = hs_scan_stream(hsStream, data.data(), data.size(), 0, hsScratch, ScanHandler, nullptr);
assert(hsError == HS_SUCCESS);

hsError = hs_close_stream(hsStream, hsScratch, CloseHandler, nullptr);
assert(hsError == HS_SUCCESS);
hsError = hs_free_database(hsDatabase);
assert(hsError == HS_SUCCESS);
hsError = hs_free_scratch(hsScratch);
assert(hsError == HS_SUCCESS);
}
```

Could you help me to solve this problem? How should we compile such cases to get correct matches on the end of stream?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.