From f84614fe066f74d111b802d582599655d0d7e3af Mon Sep 17 00:00:00 2001 From: Martin Vierula Date: Wed, 13 Apr 2022 09:37:54 -0700 Subject: [PATCH] Support PCRE2 --- CHANGES | 2 + build/pcre2.m4 | 183 +++++++++++++++++++++++++++++++++++++ configure.ac | 24 +++++ src/Makefile.am | 3 + src/operators/verify_cc.cc | 43 ++++++++- src/operators/verify_cc.h | 16 ++++ src/utils/regex.cc | 108 +++++++++++++++++++--- src/utils/regex.h | 11 ++- test/Makefile.am | 6 ++ 9 files changed, 379 insertions(+), 17 deletions(-) create mode 100644 build/pcre2.m4 diff --git a/CHANGES b/CHANGES index 220e4379fe..c65f5464f0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ v3.x.y - YYYY-MMM-DD (to be released) ------------------------------------- + - Support PCRE2 + [Issue #2668 - @martinhsv] - Support SecRequestBodyNoFilesLimit [Issue #2670 - @airween, @martinhsv] - Fix misuses of LMDB API diff --git a/build/pcre2.m4 b/build/pcre2.m4 new file mode 100644 index 0000000000..df18ebb8c5 --- /dev/null +++ b/build/pcre2.m4 @@ -0,0 +1,183 @@ +dnl Check for PCRE2 Libraries +dnl CHECK_PCRE2(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) + +AC_DEFUN([PROG_PCRE2], [ + +# Possible names for the pcre2 library/package (pkg-config) +PCRE2_POSSIBLE_LIB_NAMES="pcre2 pcre2-8" + +# Possible extensions for the library +PCRE2_POSSIBLE_EXTENSIONS="so so0 la sl dll dylib so.0.0.0" + +# Possible paths (if pkg-config was not found, proceed with the file lookup) +PCRE2_POSSIBLE_PATHS="/usr/lib /usr/local/lib /usr/local/libpcre2-8 /usr/local/pcre2 /usr/local /opt/libpcre2-8 /opt/pcre2 /opt /usr /usr/lib64 /opt/local" + +# Variables to be set by this very own script. +PCRE2_VERSION="" +PCRE2_CFLAGS="" +PCRE2_CPPFLAGS="" +PCRE2_LDADD="" +PCRE2_LDFLAGS="" + +AC_ARG_WITH( + pcre2, + AC_HELP_STRING( + [--with-pcre2=PATH], + [Path to pcre2 prefix or config script] + ) +) + +if test "x${with_pcre2}" == "xno"; then + AC_DEFINE(HAVE_PCRE2, 0, [Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no]) + AC_MSG_NOTICE([Support for PCRE2 was disabled by the utilization of --without-pcre2 or --with-pcre2=no]) + PCRE2_DISABLED=yes +else + if test "x${with_pcre2}" == "xyes"; then + PCRE2_MANDATORY=yes + AC_MSG_NOTICE([PCRE2 support was marked as mandatory by the utilization of --with-pcre2=yes]) + fi +# for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do +# CHECK_FOR_PCRE2_AT(${x}) +# if test -n "${PCRE2_VERSION}"; then +# break +# fi +# done + +# if test "x${with_pcre2}" != "xyes" or test "x${with_pcre2}" == "xyes"; then + if test "x${with_pcre2}" == "x" || test "x${with_pcre2}" == "xyes"; then + # Nothing about PCRE2 was informed, using the pkg-config to figure things out. + if test -n "${PKG_CONFIG}"; then + PCRE2_PKG_NAME="" + for x in ${PCRE2_POSSIBLE_LIB_NAMES}; do + if ${PKG_CONFIG} --exists ${x}; then + PCRE2_PKG_NAME="$x" + break + fi + done + fi + AC_MSG_NOTICE([Nothing about PCRE2 was informed during the configure phase. Trying to detect it on the platform...]) + if test -n "${PCRE2_PKG_NAME}"; then + # Package was found using the pkg-config scripts + PCRE2_VERSION="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --modversion`" + PCRE2_CFLAGS="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --cflags`" + PCRE2_LDADD="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --libs-only-l`" + PCRE2_LDFLAGS="`${PKG_CONFIG} ${PCRE2_PKG_NAME} --libs-only-L --libs-only-other`" + PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}" + else + # If pkg-config did not find anything useful, go over file lookup. + for x in ${PCRE2_POSSIBLE_PATHS}; do + CHECK_FOR_PCRE2_AT(${x}) + if test -n "${PCRE2_VERSION}"; then + break + fi + done + fi + fi + if test "x${with_pcre2}" != "x"; then + # An specific path was informed, lets check. + PCRE2_MANDATORY=yes + CHECK_FOR_PCRE2_AT(${with_pcre2}) + fi +# fi +fi + +if test -z "${PCRE2_LDADD}"; then + if test -z "${PCRE2_MANDATORY}"; then + if test -z "${PCRE2_DISABLED}"; then + AC_MSG_NOTICE([PCRE2 library was not found]) + PCRE2_FOUND=0 + else + PCRE2_FOUND=2 + fi + else + AC_MSG_ERROR([PCRE2 was explicitly referenced but it was not found]) + PCRE2_FOUND=-1 + fi +else + if test -z "${PCRE2_MANDATORY}"; then + PCRE2_FOUND=2 + AC_MSG_NOTICE([PCRE2 is disabled by default.]) + else + PCRE2_FOUND=1 + AC_MSG_NOTICE([using PCRE2 v${PCRE2_VERSION}]) + PCRE2_CFLAGS="-DWITH_PCRE2 ${PCRE2_CFLAGS}" + PCRE2_DISPLAY="${PCRE2_LDADD}, ${PCRE2_CFLAGS}" + AC_SUBST(PCRE2_VERSION) + AC_SUBST(PCRE2_LDADD) + AC_SUBST(PCRE2_LIBS) + AC_SUBST(PCRE2_LDFLAGS) + AC_SUBST(PCRE2_CFLAGS) + AC_SUBST(PCRE2_DISPLAY) + fi +fi + + +AC_SUBST(PCRE2_FOUND) + +]) # AC_DEFUN [PROG_PCRE2] + + +AC_DEFUN([CHECK_FOR_PCRE2_AT], [ + path=$1 + echo "*** LOOKING AT PATH: " ${path} + for y in ${PCRE2_POSSIBLE_EXTENSIONS}; do + for z in ${PCRE2_POSSIBLE_LIB_NAMES}; do + if test -e "${path}/${z}.${y}"; then + pcre2_lib_path="${path}/" + pcre2_lib_name="${z}" + pcre2_lib_file="${pcre2_lib_path}/${z}.${y}" + break + fi + if test -e "${path}/lib${z}.${y}"; then + pcre2_lib_path="${path}/" + pcre2_lib_name="${z}" + pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" + break + fi + if test -e "${path}/lib/lib${z}.${y}"; then + pcre2_lib_path="${path}/lib/" + pcre2_lib_name="${z}" + pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" + break + fi + if test -e "${path}/lib/x86_64-linux-gnu/lib${z}.${y}"; then + pcre2_lib_path="${path}/lib/x86_64-linux-gnu/" + pcre2_lib_name="${z}" + pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" + break + fi + if test -e "${path}/lib/i386-linux-gnu/lib${z}.${y}"; then + pcre2_lib_path="${path}/lib/i386-linux-gnu/" + pcre2_lib_name="${z}" + pcre2_lib_file="${pcre2_lib_path}/lib${z}.${y}" + break + fi + done + if test -n "$pcre2_lib_path"; then + break + fi + done + if test -e "${path}/include/pcre2.h"; then + pcre2_inc_path="${path}/include" + elif test -e "${path}/pcre2.h"; then + pcre2_inc_path="${path}" + elif test -e "${path}/include/pcre2/pcre2.h"; then + pcre2_inc_path="${path}/include" + fi + + if test -n "${pcre2_lib_path}"; then + AC_MSG_NOTICE([PCRE2 library found at: ${pcre2_lib_file}]) + fi + + if test -n "${pcre2_inc_path}"; then + AC_MSG_NOTICE([PCRE2 headers found at: ${pcre2_inc_path}]) + fi + + if test -n "${pcre2_lib_path}" -a -n "${pcre2_inc_path}"; then + # TODO: Compile a piece of code to check the version. + PCRE2_CFLAGS="-I${pcre2_inc_path}" + PCRE2_LDADD="-l${pcre2_lib_name}" + PCRE2_LDFLAGS="-L${pcre2_lib_path}" + PCRE2_DISPLAY="${pcre2_lib_file}, ${pcre2_inc_path}" + fi +]) # AC_DEFUN [CHECK_FOR_PCRE2_AT] diff --git a/configure.ac b/configure.ac index 20163e1e00..cd8241815c 100644 --- a/configure.ac +++ b/configure.ac @@ -129,6 +129,13 @@ CHECK_LIBXML2 CHECK_PCRE +# +# Check for pcre2 +# +PROG_PCRE2 +AM_CONDITIONAL([PCRE2_CFLAGS], [test "PCRE2_CFLAGS" != ""]) + + # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([string]) @@ -555,6 +562,23 @@ if test "x$LUA_FOUND" = "x2"; then fi +## PCRE2 +if test "x$PCRE2_FOUND" = "x0"; then + echo " + PCRE2 ....not found" +fi +if test "x$PCRE2_FOUND" = "x1"; then + echo -n " + PCRE2 ....found " + if ! test "x$PCRE2_VERSION" = "x"; then + echo "v${PCRE2_VERSION}" + else + echo "" + fi + echo " ${PCRE2_DISPLAY}" +fi +if test "x$PCRE2_FOUND" = "x2"; then + echo " + PCRE2 ....disabled" +fi + echo " " echo " Other Options" if test $buildTestUtilities = true; then diff --git a/src/Makefile.am b/src/Makefile.am index 89eaa74eec..605f22dbc7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -324,6 +324,7 @@ libmodsecurity_la_CPPFLAGS = \ $(YAJL_CFLAGS) \ $(LMDB_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(SSDEEP_CFLAGS) \ $(MAXMIND_CFLAGS) \ $(LUA_CFLAGS) \ @@ -339,6 +340,7 @@ libmodsecurity_la_LDFLAGS = \ $(LMDB_LDFLAGS) \ $(LUA_LDFLAGS) \ $(PCRE_LDFLAGS) \ + $(PCRE2_LDFLAGS) \ $(SSDEEP_LDFLAGS) \ $(MAXMIND_LDFLAGS) \ $(YAJL_LDFLAGS) \ @@ -355,6 +357,7 @@ libmodsecurity_la_LIBADD = \ ../others/libinjection.la \ ../others/libmbedtls.la \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(MAXMIND_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) diff --git a/src/operators/verify_cc.cc b/src/operators/verify_cc.cc index a0d76cc376..9cbe8bb8ad 100644 --- a/src/operators/verify_cc.cc +++ b/src/operators/verify_cc.cc @@ -15,24 +15,28 @@ #include "src/operators/verify_cc.h" -#include #include #include #include #include "src/operators/operator.h" +#ifndef WITH_PCRE2 #if PCRE_HAVE_JIT #define pcre_study_opt PCRE_STUDY_JIT_COMPILE #else #define pcre_study_opt 0 #endif +#endif namespace modsecurity { namespace operators { VerifyCC::~VerifyCC() { +#if WITH_PCRE2 + pcre2_code_free(m_pc); +#else if (m_pc != NULL) { pcre_free(m_pc); m_pc = NULL; @@ -45,6 +49,7 @@ VerifyCC::~VerifyCC() { #endif m_pce = NULL; } +#endif } /** @@ -90,6 +95,22 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) { bool VerifyCC::init(const std::string ¶m2, std::string *error) { +#ifdef WITH_PCRE2 + PCRE2_SPTR pcre2_pattern = reinterpret_cast(m_param.c_str()); + uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE); + int errornumber = 0; + PCRE2_SIZE erroroffset = 0; + m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED, + pcre2_options, &errornumber, &erroroffset, NULL); + if (m_pc == NULL) { + return false; + } else { + m_match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + if (m_match_data == NULL) { + return false; + } + } +#else const char *errptr = NULL; int erroffset = 0; @@ -112,6 +133,7 @@ bool VerifyCC::init(const std::string ¶m2, std::string *error) { error->assign(errptr); return false; } +#endif return true; } @@ -119,11 +141,25 @@ bool VerifyCC::init(const std::string ¶m2, std::string *error) { bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, const std::string& i, std::shared_ptr ruleMessage) { +#ifdef WITH_PCRE2 + PCRE2_SIZE offset = 0; + size_t target_length = i.length(); + PCRE2_SPTR pcre2_i = reinterpret_cast(i.c_str()); + + for (offset = 0; offset < target_length; offset++) { + int ret = pcre2_match(m_pc, pcre2_i, target_length, offset, 0, m_match_data, NULL); + + /* If there was no match, then we are done. */ + if (ret < 0) { + break; + } + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); + +#else int offset = 0; int target_length = i.length(); for (offset = 0; offset < target_length; offset++) { - std::string match; int ovector[33]; memset(ovector, 0, sizeof(ovector)); int ret = pcre_exec(m_pc, m_pce, i.c_str(), i.size(), offset, @@ -136,8 +172,9 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, if (ret < 0) { return false; } +#endif if (ret > 0) { - match = std::string(i, ovector[0], ovector[1] - ovector[0]); + std::string match = std::string(i, ovector[0], ovector[1] - ovector[0]); int is_cc = luhnVerify(match.c_str(), match.size()); if (is_cc) { if (t) { diff --git a/src/operators/verify_cc.h b/src/operators/verify_cc.h index dc82492c9a..6bbed920f1 100644 --- a/src/operators/verify_cc.h +++ b/src/operators/verify_cc.h @@ -16,7 +16,14 @@ #ifndef SRC_OPERATORS_VERIFY_CC_H_ #define SRC_OPERATORS_VERIFY_CC_H_ +#if WITH_PCRE2 +#define PCRE2_CODE_UNIT_WIDTH 8 +#include +#else #include +#endif + + #include #include #include @@ -32,7 +39,11 @@ class VerifyCC : public Operator { explicit VerifyCC(std::unique_ptr param) : Operator("VerifyCC", std::move(param)), m_pc(NULL), +#if WITH_PCRE2 + m_match_data(NULL) { } +#else m_pce(NULL) { } +#endif ~VerifyCC(); bool evaluate(Transaction *t, RuleWithActions *rule, @@ -40,8 +51,13 @@ class VerifyCC : public Operator { std::shared_ptr ruleMessage) override; bool init(const std::string ¶m, std::string *error) override; private: +#if WITH_PCRE2 + pcre2_code *m_pc; + pcre2_match_data *m_match_data; +#else pcre *m_pc; pcre_extra *m_pce; +#endif static int luhnVerify(const char *ccnumber, int len); }; diff --git a/src/utils/regex.cc b/src/utils/regex.cc index 82a88c2b17..b2536aefb2 100644 --- a/src/utils/regex.cc +++ b/src/utils/regex.cc @@ -15,7 +15,6 @@ #include "src/utils/regex.h" -#include #include #include @@ -24,17 +23,27 @@ #include "src/utils/geo_lookup.h" +#ifndef WITH_PCRE2 #if PCRE_HAVE_JIT #define pcre_study_opt PCRE_STUDY_JIT_COMPILE #else #define pcre_study_opt 0 #endif +#endif namespace modsecurity { namespace Utils { // Helper function to tell us if the current config indicates CRLF is a valid newline sequence bool crlfIsNewline() { +#if WITH_PCRE2 + uint32_t newline = 0; + pcre2_config(PCRE2_CONFIG_NEWLINE, &newline); + bool crlf_is_newline = + newline == PCRE2_NEWLINE_ANY || + newline == PCRE2_NEWLINE_CRLF || + newline == PCRE2_NEWLINE_ANYCRLF; +#else int d = 0; pcre_config(PCRE_CONFIG_NEWLINE, &d); @@ -48,12 +57,26 @@ bool crlfIsNewline() { option_bits == PCRE_NEWLINE_ANY || option_bits == PCRE_NEWLINE_CRLF || option_bits == PCRE_NEWLINE_ANYCRLF; - +#endif return crlf_is_newline; } Regex::Regex(const std::string& pattern_, bool ignoreCase) : pattern(pattern_.empty() ? ".*" : pattern_) { +#if WITH_PCRE2 + PCRE2_SPTR pcre2_pattern = reinterpret_cast(pattern.c_str()); + uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE); + if (ignoreCase) { + pcre2_options |= PCRE2_CASELESS; + } + int errornumber = 0; + PCRE2_SIZE erroroffset = 0; + m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED, + pcre2_options, &errornumber, &erroroffset, NULL); + if (m_pc != NULL) { + m_match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + } +#else const char *errptr = NULL; int erroffset; int flags = (PCRE_DOTALL|PCRE_MULTILINE); @@ -65,10 +88,15 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase) &errptr, &erroffset, NULL); m_pce = pcre_study(m_pc, pcre_study_opt, &errptr); +#endif } Regex::~Regex() { +#if WITH_PCRE2 + pcre2_match_data_free(m_match_data); + pcre2_code_free(m_pc); +#else if (m_pc != NULL) { pcre_free(m_pc); m_pc = NULL; @@ -81,29 +109,39 @@ Regex::~Regex() { #endif m_pce = NULL; } +#endif } std::list Regex::searchAll(const std::string& s) const { + std::list retList; + int rc; +#ifdef WITH_PCRE2 + PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); + PCRE2_SIZE offset = 0; + + do { + rc = pcre2_match(m_pc, pcre2_s, s.length(), + offset, 0, m_match_data, NULL); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); +#else const char *subject = s.c_str(); - const std::string tmpString = std::string(s.c_str(), s.size()); int ovector[OVECCOUNT]; - int rc, i, offset = 0; - std::list retList; + int offset = 0; do { rc = pcre_exec(m_pc, m_pce, subject, s.size(), offset, 0, ovector, OVECCOUNT); - - for (i = 0; i < rc; i++) { +#endif + for (int i = 0; i < rc; i++) { size_t start = ovector[2*i]; size_t end = ovector[2*i+1]; size_t len = end - start; if (end > s.size()) { - rc = 0; + rc = -1; break; } - std::string match = std::string(tmpString, start, len); + std::string match = std::string(s, start, len); offset = start + len; retList.push_front(SMatch(match, start)); @@ -118,10 +156,16 @@ std::list Regex::searchAll(const std::string& s) const { } bool Regex::searchOneMatch(const std::string& s, std::vector& captures) const { +#ifdef WITH_PCRE2 + PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); + int rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, 0, m_match_data, NULL); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); +#else const char *subject = s.c_str(); int ovector[OVECCOUNT]; int rc = pcre_exec(m_pc, m_pce, subject, s.size(), 0, 0, ovector, OVECCOUNT); +#endif for (int i = 0; i < rc; i++) { size_t start = ovector[2*i]; @@ -138,9 +182,22 @@ bool Regex::searchOneMatch(const std::string& s, std::vector& cap } bool Regex::searchGlobal(const std::string& s, std::vector& captures) const { - const char *subject = s.c_str(); - bool prev_match_zero_length = false; +#ifdef WITH_PCRE2 + PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); + PCRE2_SIZE startOffset = 0; + + while (startOffset <= s.length()) { + uint32_t pcre2_options = 0; + if (prev_match_zero_length) { + pcre2_options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; + } + int rc = pcre2_match(m_pc, pcre2_s, s.length(), + startOffset, pcre2_options, m_match_data, NULL); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); + +#else + const char *subject = s.c_str(); int startOffset = 0; while (startOffset <= s.length()) { @@ -151,6 +208,7 @@ bool Regex::searchGlobal(const std::string& s, std::vector& captu } int rc = pcre_exec(m_pc, m_pce, subject, s.length(), startOffset, pcre_options, ovector, OVECCOUNT); +#endif if (rc > 0) { size_t firstGroupForThisFullMatch = captures.size(); for (int i = 0; i < rc; i++) { @@ -169,8 +227,13 @@ bool Regex::searchGlobal(const std::string& s, std::vector& captu startOffset = end; prev_match_zero_length = false; } else { - // zero-length match; modify next match attempt to avoid infinite loop - prev_match_zero_length = true; + if ( startOffset == s.length()) { + // zero-length match at end of string; force end of while-loop + startOffset++; + } else { + // zero-length match mid-string; adjust next match attempt + prev_match_zero_length = true; + } } } } @@ -196,11 +259,20 @@ bool Regex::searchGlobal(const std::string& s, std::vector& captu } int Regex::search(const std::string& s, SMatch *match) const { +#ifdef WITH_PCRE2 + PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); + int ret = pcre2_match(m_pc, pcre2_s, s.length(), + 0, 0, m_match_data, NULL) > 0; + + if (ret > 0) { // match + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); +#else int ovector[OVECCOUNT]; int ret = pcre_exec(m_pc, m_pce, s.c_str(), s.size(), 0, 0, ovector, OVECCOUNT) > 0; if (ret > 0) { +#endif *match = SMatch( std::string(s, ovector[ret-1], ovector[ret] - ovector[ret-1]), 0); @@ -210,9 +282,19 @@ int Regex::search(const std::string& s, SMatch *match) const { } int Regex::search(const std::string& s) const { +#ifdef WITH_PCRE2 + PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); + int rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, 0, m_match_data, NULL); + if (rc > 0) { + return 1; // match + } else { + return 0; // no match + } +#else int ovector[OVECCOUNT]; return pcre_exec(m_pc, m_pce, s.c_str(), s.size(), 0, 0, ovector, OVECCOUNT) > 0; +#endif } } // namespace Utils diff --git a/src/utils/regex.h b/src/utils/regex.h index 1e3a48d74c..a55c60633e 100644 --- a/src/utils/regex.h +++ b/src/utils/regex.h @@ -12,8 +12,12 @@ * directly using the email address security@modsecurity.org. * */ - +#if WITH_PCRE2 +#define PCRE2_CODE_UNIT_WIDTH 8 +#include +#else #include +#endif #include #include @@ -76,8 +80,13 @@ class Regex { const std::string pattern; private: +#if WITH_PCRE2 + pcre2_code *m_pc; + pcre2_match_data *m_match_data; +#else pcre *m_pc = NULL; pcre_extra *m_pce = NULL; +#endif }; diff --git a/test/Makefile.am b/test/Makefile.am index 9a719342dd..9237a87492 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -50,6 +50,7 @@ unit_tests_LDADD = \ $(LMDB_LDADD) \ $(LUA_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) @@ -81,6 +82,7 @@ unit_tests_CPPFLAGS = \ $(GLOBAL_CPPFLAGS) \ $(LMDB_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(YAJL_CFLAGS) \ $(LUA_CFLAGS) \ $(SSDEEP_CFLAGS) \ @@ -104,6 +106,7 @@ regression_tests_LDADD = \ $(LMDB_LDADD) \ $(LUA_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) @@ -137,6 +140,7 @@ regression_tests_CPPFLAGS = \ $(LUA_CFLAGS) \ $(SSDEEP_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(YAJL_CFLAGS) \ $(LIBXML2_CFLAGS) @@ -157,6 +161,7 @@ rules_optimization_LDADD = \ $(LMDB_LDADD) \ $(LUA_LDADD) \ $(PCRE_LDADD) \ + $(PCRE2_LDADD) \ $(SSDEEP_LDADD) \ $(YAJL_LDADD) @@ -188,6 +193,7 @@ rules_optimization_CPPFLAGS = \ $(LUA_CFLAGS) \ $(SSDEEP_CFLAGS) \ $(PCRE_CFLAGS) \ + $(PCRE2_CFLAGS) \ $(YAJL_CFLAGS) \ $(LIBXML2_CFLAGS)