From c7d0ab00ca1084f4c9d31f6d71110557ad64a649 Mon Sep 17 00:00:00 2001 From: prudvi Date: Thu, 23 Jul 2026 13:19:25 +0530 Subject: [PATCH 1/6] fix linker issue Signed-off-by: prudvi --- unit/hyperscan/arg_checks.cpp | 58 ++++++++++++++++++++++++++--------- unit/hyperscan/single.cpp | 5 ++- 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/unit/hyperscan/arg_checks.cpp b/unit/hyperscan/arg_checks.cpp index 6a2fa650d..eb0b6d82b 100644 --- a/unit/hyperscan/arg_checks.cpp +++ b/unit/hyperscan/arg_checks.cpp @@ -28,6 +28,10 @@ #include "config.h" +#include +#include +#include + #include "gtest/gtest.h" #include "hs.h" #include "database.h" @@ -57,36 +61,60 @@ int singleHandler(unsigned id, unsigned long long from, namespace /* anonymous */ { +static void makeDatabaseWritable(hs_database *db) { + if (!db) { + return; + } + long ps_raw = sysconf(_SC_PAGESIZE); + if (ps_raw <= 0) { + return; + } + size_t ps = (size_t)ps_raw; + /* Verify page size is a power of two. */ + if ((ps & (ps - 1)) != 0) { + return; + } + if ((uintptr_t)db & (ps - 1)) { + return; + } + size_t db_len = sizeof(struct hs_database) + db->length; + /* Guard against overflow in round-up arithmetic. */ + if (db_len > SIZE_MAX - ps) { + return; + } + size_t rounded = (db_len + ps - 1) & ~(ps - 1); + if (rounded < db_len || rounded == 0) { + return; + } + int ret = mprotect(db, rounded, PROT_READ | PROT_WRITE); + (void)ret; /* intentionally ignore in test code */ +} + // Break the magic number of the given database. void breakDatabaseMagic(hs_database *db) { + makeDatabaseWritable(db); // database magic should be 0xdbdb at the start - size_t db_len = sizeof(struct hs_database) + db->length; - hs_db_unprotect(db, db_len); ASSERT_TRUE(memcmp("\xdb\xdb", db, 2) == 0); *(char *)db = 0xdc; } // Break the version number of the given database. void breakDatabaseVersion(hs_database *db) { + makeDatabaseWritable(db); // database version is the second u32 - size_t db_len = sizeof(struct hs_database) + db->length; - hs_db_unprotect(db, db_len); *((char *)db + 4) += 1; } // Break the platform data of the given database. void breakDatabasePlatform(hs_database *db) { + makeDatabaseWritable(db); // database platform is an aligned u64a 16 bytes in - size_t db_len = sizeof(struct hs_database) + db->length; - hs_db_unprotect(db, db_len); memset((char *)db + 16, 0xff, 8); } // Break the alignment of the bytecode for the given database. void breakDatabaseBytecode(hs_database *db) { - // bytecode ptr is a u32 at offsetof(hs_database, bytecode) - size_t db_len = sizeof(struct hs_database) + db->length; - hs_db_unprotect(db, db_len); + makeDatabaseWritable(db); unsigned int *bytecode = (unsigned int *)((char *)db + offsetof(struct hs_database, bytecode)); ASSERT_NE(0U, *bytecode); ASSERT_EQ(0U, (size_t)((char *)db + *bytecode) % 16U); @@ -925,7 +953,7 @@ TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseMagic) { // teardown err = hs_free_scratch(scratch); ASSERT_EQ(HS_SUCCESS, err); - hs_db_free(db, db_len1); + hs_free_database(db); } // hs_scan: Call with a database with broken version @@ -1131,7 +1159,7 @@ TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseMagic) { // teardown err = hs_free_scratch(scratch); ASSERT_EQ(HS_SUCCESS, err); - hs_db_free(db, db_len2); + hs_free_database(db); } // hs_scan_vector: Call with a database with broken version @@ -1408,7 +1436,7 @@ TEST(HyperscanArgChecks, AllocScratchBadDatabaseMagic) { ASSERT_EQ(HS_INVALID, err); // teardown - hs_db_free(db, db_len3); + hs_free_database(db); } // hs_alloc_scratch: Call with broken database version @@ -1490,7 +1518,7 @@ TEST(HyperscanArgChecks, AllocScratchBadDatabaseCRC) { ASSERT_EQ(HS_SUCCESS, err); // for want of a better case, corrupt the "middle byte" of the database. - hs_db_unprotect(db, len); + makeDatabaseWritable(db); char *mid = (char *)db + len/2; *mid += 17; @@ -1575,14 +1603,14 @@ TEST(HyperscanArgChecks, StreamSizeBogusDatabase) { ASSERT_EQ(HS_SUCCESS, err); ASSERT_LT(0U, len); - hs_db_unprotect(db, len); + makeDatabaseWritable(db); memset(db, 0xf0, len); size_t sz; err = hs_stream_size(db, &sz); ASSERT_EQ(HS_INVALID, err); - hs_db_free(db, len); + hs_free_database(db); } // hs_stream_size: Call with a block-mode database diff --git a/unit/hyperscan/single.cpp b/unit/hyperscan/single.cpp index bbe116a0e..6732fb33b 100644 --- a/unit/hyperscan/single.cpp +++ b/unit/hyperscan/single.cpp @@ -244,9 +244,8 @@ class HyperscanTestRuntime size_t origSize; err = hs_database_size(db, &origSize); ASSERT_EQ(HS_SUCCESS, err); - hs_db_unprotect(db, origSize); - memset(db, 0xff, origSize); - hs_db_free(db, origSize); + hs_free_database(db); + db = nullptr; // relocate to 16 different alignments, ensuring that we can // deserialize from any string From a719651398a769669ba2417da3b62815d9155d0d Mon Sep 17 00:00:00 2001 From: prudvi Date: Thu, 23 Jul 2026 13:22:58 +0530 Subject: [PATCH 2/6] fix compile warnings Signed-off-by: prudvi --- src/nfa/nfa_rev_api.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nfa/nfa_rev_api.h b/src/nfa/nfa_rev_api.h index ea9bc411c..7fab4c2de 100644 --- a/src/nfa/nfa_rev_api.h +++ b/src/nfa/nfa_rev_api.h @@ -104,7 +104,7 @@ size_t nfaRevAccel_i(const struct NFA *nfa, const u8 *buffer, size_t length) { break; case ACCEL_RDEOD: DEBUG_PRINTF("ACCEL_RDEOD\n"); - if (length < nfa->rAccelOffset + 1) { + if (length < (size_t)nfa->rAccelOffset + 1) { break; } if (unaligned_load_u16(buffer + length - nfa->rAccelOffset) != @@ -114,7 +114,7 @@ size_t nfaRevAccel_i(const struct NFA *nfa, const u8 *buffer, size_t length) { break; case ACCEL_RDEOD_NOCASE: DEBUG_PRINTF("ACCEL_RDEOD_NOCASE\n"); - if (length < nfa->rAccelOffset + 1) { + if (length < (size_t)nfa->rAccelOffset + 1) { break; } if ((unaligned_load_u16(buffer + length - nfa->rAccelOffset) & From 44ebf308a293f9188cd9a8fc93af6098f9b80d98 Mon Sep 17 00:00:00 2001 From: prudvi Date: Wed, 29 Jul 2026 11:50:22 +0530 Subject: [PATCH 3/6] fix unit-hyperscan link error and unused variables in arg_checks Signed-off-by: prudvi --- unit/hyperscan/arg_checks.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/unit/hyperscan/arg_checks.cpp b/unit/hyperscan/arg_checks.cpp index eb0b6d82b..8eea43d07 100644 --- a/unit/hyperscan/arg_checks.cpp +++ b/unit/hyperscan/arg_checks.cpp @@ -29,8 +29,10 @@ #include "config.h" #include +#ifndef _WIN32 #include #include +#endif #include "gtest/gtest.h" #include "hs.h" @@ -61,6 +63,7 @@ int singleHandler(unsigned id, unsigned long long from, namespace /* anonymous */ { +#ifndef _WIN32 static void makeDatabaseWritable(hs_database *db) { if (!db) { return; @@ -89,6 +92,15 @@ static void makeDatabaseWritable(hs_database *db) { int ret = mprotect(db, rounded, PROT_READ | PROT_WRITE); (void)ret; /* intentionally ignore in test code */ } +#else +static void makeDatabaseWritable(hs_database *db) { + if (!db) { + return; + } + size_t db_len = sizeof(struct hs_database) + db->length; + hs_db_unprotect(db, db_len); +} +#endif // Break the magic number of the given database. void breakDatabaseMagic(hs_database *db) { @@ -944,7 +956,6 @@ TEST(HyperscanArgChecks, ScanBlockBrokenDatabaseMagic) { ASSERT_TRUE(scratch != nullptr); // break the database here, after scratch alloc - size_t db_len1 = sizeof(struct hs_database) + db->length; breakDatabaseMagic(db); err = hs_scan(db, "data", 4, 0, scratch, dummy_cb, nullptr); @@ -1148,7 +1159,6 @@ TEST(HyperscanArgChecks, ScanVectorBrokenDatabaseMagic) { ASSERT_TRUE(scratch != nullptr); // break the database here, after scratch alloc - size_t db_len2 = sizeof(struct hs_database) + db->length; breakDatabaseMagic(db); const char *data[] = {"data", "data"}; @@ -1428,7 +1438,6 @@ TEST(HyperscanArgChecks, AllocScratchBadDatabaseMagic) { ASSERT_EQ(HS_SUCCESS, err); ASSERT_TRUE(db != nullptr); - size_t db_len3 = sizeof(struct hs_database) + db->length; breakDatabaseMagic(db); hs_scratch_t *scratch = nullptr; From 904e4b788486e75c38c497c25a17a65fa2ef458d Mon Sep 17 00:00:00 2001 From: prudvi Date: Thu, 30 Jul 2026 10:35:58 +0530 Subject: [PATCH 4/6] fix compile warning --- src/db_protect.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/db_protect.c b/src/db_protect.c index 8fab64e93..8ee3f832f 100644 --- a/src/db_protect.c +++ b/src/db_protect.c @@ -24,6 +24,9 @@ implied warranties, other than those that are expressly stated in the License. * memory may not be page-aligned or mmap-backed). */ +#ifndef _WIN32 +#define _GNU_SOURCE +#endif #include "allocator.h" #include "database.h" #include "hs_common.h" From ce219b552434d688c0cf54fff86b2e842cb424c5 Mon Sep 17 00:00:00 2001 From: prudvi Date: Thu, 30 Jul 2026 11:15:11 +0530 Subject: [PATCH 5/6] suppress GCC 12+ false-positive -Wstringop-overread warnings --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 80492d1ef..062417d85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -474,6 +474,9 @@ endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Intel") SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -diag-error 10006 -diag-disable 68 -diag-disable 177 -diag-disable 186 -diag-disable 2304 -diag-disable 2305 -diag-disable 2338 -diag-disable 1418 -diag-disable 1170 -diag-disable 3373 -diag-disable 279 -diag-disable=remark") endif() +if(CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.0") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overread -Wno-stringop-overflow") +endif() endif() if (NOT FAT_RUNTIME) From f0cc142c33e80a1be16b84cc39679e9fb27fb12c Mon Sep 17 00:00:00 2001 From: prudvi Date: Fri, 31 Jul 2026 17:15:16 +0530 Subject: [PATCH 6/6] cmake version update --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 062417d85..79a900086 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 2.8.11) +cmake_minimum_required (VERSION 3.5.0) project (hyperscan C CXX) set (HS_MAJOR_VERSION 5)