From 0362af4db4133f182a6a349874033b312add6aaa Mon Sep 17 00:00:00 2001 From: Martin Vierula Date: Fri, 20 May 2022 06:58:31 -0700 Subject: [PATCH] Move PCRE2 match block from member variable --- CHANGES | 2 ++ src/operators/verify_cc.cc | 17 ++++++++------- src/operators/verify_cc.h | 5 ++--- src/utils/regex.cc | 43 ++++++++++++++++++++++++-------------- src/utils/regex.h | 1 - 5 files changed, 41 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index c6673d9d..faf6c948 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ v3.x.y - YYYY-MMM-DD (to be released) ------------------------------------- + - Move PCRE2 match block from member variable + [Issue #2745 - @martinhsv] - Add SecArgumentsLimit, 200007 to modsecurity.conf-recommended [Issue #2738 - @jleproust, @martinhsv] - Fix memory leak when concurrent log includes REMOTE_USER diff --git a/src/operators/verify_cc.cc b/src/operators/verify_cc.cc index 9cbe8bb8..bdb63f34 100644 --- a/src/operators/verify_cc.cc +++ b/src/operators/verify_cc.cc @@ -104,11 +104,6 @@ bool VerifyCC::init(const std::string ¶m2, std::string *error) { 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; @@ -145,15 +140,16 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, PCRE2_SIZE offset = 0; size_t target_length = i.length(); PCRE2_SPTR pcre2_i = reinterpret_cast(i.c_str()); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); for (offset = 0; offset < target_length; offset++) { - int ret = pcre2_match(m_pc, pcre2_i, target_length, offset, 0, m_match_data, NULL); + int ret = pcre2_match(m_pc, pcre2_i, target_length, offset, 0, 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); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else int offset = 0; @@ -188,11 +184,18 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule, "\" at " + i + ". [offset " + std::to_string(offset) + "]"); } +#ifdef WITH_PCRE2 + pcre2_match_data_free(match_data); +#endif return true; } } } +#ifdef WITH_PCRE2 + pcre2_match_data_free(match_data); +#endif + return false; } diff --git a/src/operators/verify_cc.h b/src/operators/verify_cc.h index 6bbed920..91195378 100644 --- a/src/operators/verify_cc.h +++ b/src/operators/verify_cc.h @@ -38,10 +38,10 @@ class VerifyCC : public Operator { /** @ingroup ModSecurity_Operator */ explicit VerifyCC(std::unique_ptr param) : Operator("VerifyCC", std::move(param)), - m_pc(NULL), #if WITH_PCRE2 - m_match_data(NULL) { } + m_pc(NULL) { } #else + m_pc(NULL), m_pce(NULL) { } #endif ~VerifyCC(); @@ -53,7 +53,6 @@ class VerifyCC : public Operator { private: #if WITH_PCRE2 pcre2_code *m_pc; - pcre2_match_data *m_match_data; #else pcre *m_pc; pcre_extra *m_pce; diff --git a/src/utils/regex.cc b/src/utils/regex.cc index 9b80fbf3..45878ed0 100644 --- a/src/utils/regex.cc +++ b/src/utils/regex.cc @@ -73,12 +73,6 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase) 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); - if (m_match_data == NULL) { - m_pc = NULL; - } - } #else const char *errptr = NULL; int erroffset; @@ -97,7 +91,6 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase) Regex::~Regex() { #if WITH_PCRE2 - pcre2_match_data_free(m_match_data); pcre2_code_free(m_pc); #else if (m_pc != NULL) { @@ -123,10 +116,11 @@ std::list Regex::searchAll(const std::string& s) const { PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); PCRE2_SIZE offset = 0; + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); 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); + offset, 0, match_data, NULL); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else const char *subject = s.c_str(); int ovector[OVECCOUNT]; @@ -155,14 +149,18 @@ std::list Regex::searchAll(const std::string& s) const { } } while (rc > 0); +#ifdef WITH_PCRE2 + pcre2_match_data_free(match_data); +#endif return retList; } 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); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + int rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, NULL); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else const char *subject = s.c_str(); int ovector[OVECCOUNT]; @@ -181,6 +179,9 @@ bool Regex::searchOneMatch(const std::string& s, std::vector& cap captures.push_back(capture); } +#ifdef WITH_PCRE2 + pcre2_match_data_free(match_data); +#endif return (rc > 0); } @@ -190,14 +191,15 @@ bool Regex::searchGlobal(const std::string& s, std::vector& captu PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); PCRE2_SIZE startOffset = 0; + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); 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); + startOffset, pcre2_options, match_data, NULL); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else const char *subject = s.c_str(); @@ -258,17 +260,21 @@ bool Regex::searchGlobal(const std::string& s, std::vector& captu } } +#ifdef WITH_PCRE2 + pcre2_match_data_free(match_data); +#endif return (captures.size() > 0); } int Regex::search(const std::string& s, SMatch *match) const { #ifdef WITH_PCRE2 PCRE2_SPTR pcre2_s = reinterpret_cast(s.c_str()); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); int ret = pcre2_match(m_pc, pcre2_s, s.length(), - 0, 0, m_match_data, NULL) > 0; + 0, 0, match_data, NULL) > 0; if (ret > 0) { // match - PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); + PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data); #else int ovector[OVECCOUNT]; int ret = pcre_exec(m_pc, m_pce, s.c_str(), @@ -281,13 +287,18 @@ int Regex::search(const std::string& s, SMatch *match) const { 0); } +#ifdef WITH_PCRE2 + pcre2_match_data_free(match_data); +#endif return ret; } 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); + pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL); + int rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, NULL); + pcre2_match_data_free(match_data); if (rc > 0) { return 1; // match } else { diff --git a/src/utils/regex.h b/src/utils/regex.h index 19a1eee5..6bd8ce92 100644 --- a/src/utils/regex.h +++ b/src/utils/regex.h @@ -85,7 +85,6 @@ class Regex { private: #if WITH_PCRE2 pcre2_code *m_pc; - pcre2_match_data *m_match_data; #else pcre *m_pc = NULL; pcre_extra *m_pce = NULL;