Move PCRE2 match block from member variable

This commit is contained in:
Martin Vierula 2022-05-20 06:58:31 -07:00
parent 770662c0da
commit 0362af4db4
No known key found for this signature in database
GPG Key ID: F2FC4E45883BCBA4
5 changed files with 41 additions and 27 deletions

View File

@ -1,6 +1,8 @@
v3.x.y - YYYY-MMM-DD (to be released) 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 - Add SecArgumentsLimit, 200007 to modsecurity.conf-recommended
[Issue #2738 - @jleproust, @martinhsv] [Issue #2738 - @jleproust, @martinhsv]
- Fix memory leak when concurrent log includes REMOTE_USER - Fix memory leak when concurrent log includes REMOTE_USER

View File

@ -104,11 +104,6 @@ bool VerifyCC::init(const std::string &param2, std::string *error) {
pcre2_options, &errornumber, &erroroffset, NULL); pcre2_options, &errornumber, &erroroffset, NULL);
if (m_pc == NULL) { if (m_pc == NULL) {
return false; return false;
} else {
m_match_data = pcre2_match_data_create_from_pattern(m_pc, NULL);
if (m_match_data == NULL) {
return false;
}
} }
#else #else
const char *errptr = NULL; const char *errptr = NULL;
@ -145,15 +140,16 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,
PCRE2_SIZE offset = 0; PCRE2_SIZE offset = 0;
size_t target_length = i.length(); size_t target_length = i.length();
PCRE2_SPTR pcre2_i = reinterpret_cast<PCRE2_SPTR>(i.c_str()); PCRE2_SPTR pcre2_i = reinterpret_cast<PCRE2_SPTR>(i.c_str());
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL);
for (offset = 0; offset < target_length; offset++) { 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 there was no match, then we are done. */
if (ret < 0) { if (ret < 0) {
break; break;
} }
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
#else #else
int offset = 0; int offset = 0;
@ -188,11 +184,18 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,
"\" at " + i + ". [offset " + "\" at " + i + ". [offset " +
std::to_string(offset) + "]"); std::to_string(offset) + "]");
} }
#ifdef WITH_PCRE2
pcre2_match_data_free(match_data);
#endif
return true; return true;
} }
} }
} }
#ifdef WITH_PCRE2
pcre2_match_data_free(match_data);
#endif
return false; return false;
} }

View File

@ -38,10 +38,10 @@ class VerifyCC : public Operator {
/** @ingroup ModSecurity_Operator */ /** @ingroup ModSecurity_Operator */
explicit VerifyCC(std::unique_ptr<RunTimeString> param) explicit VerifyCC(std::unique_ptr<RunTimeString> param)
: Operator("VerifyCC", std::move(param)), : Operator("VerifyCC", std::move(param)),
m_pc(NULL),
#if WITH_PCRE2 #if WITH_PCRE2
m_match_data(NULL) { } m_pc(NULL) { }
#else #else
m_pc(NULL),
m_pce(NULL) { } m_pce(NULL) { }
#endif #endif
~VerifyCC(); ~VerifyCC();
@ -53,7 +53,6 @@ class VerifyCC : public Operator {
private: private:
#if WITH_PCRE2 #if WITH_PCRE2
pcre2_code *m_pc; pcre2_code *m_pc;
pcre2_match_data *m_match_data;
#else #else
pcre *m_pc; pcre *m_pc;
pcre_extra *m_pce; pcre_extra *m_pce;

View File

@ -73,12 +73,6 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase)
PCRE2_SIZE erroroffset = 0; PCRE2_SIZE erroroffset = 0;
m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED, m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED,
pcre2_options, &errornumber, &erroroffset, NULL); 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 #else
const char *errptr = NULL; const char *errptr = NULL;
int erroffset; int erroffset;
@ -97,7 +91,6 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase)
Regex::~Regex() { Regex::~Regex() {
#if WITH_PCRE2 #if WITH_PCRE2
pcre2_match_data_free(m_match_data);
pcre2_code_free(m_pc); pcre2_code_free(m_pc);
#else #else
if (m_pc != NULL) { if (m_pc != NULL) {
@ -123,10 +116,11 @@ std::list<SMatch> Regex::searchAll(const std::string& s) const {
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str()); PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());
PCRE2_SIZE offset = 0; PCRE2_SIZE offset = 0;
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL);
do { do {
rc = pcre2_match(m_pc, pcre2_s, s.length(), rc = pcre2_match(m_pc, pcre2_s, s.length(),
offset, 0, m_match_data, NULL); offset, 0, match_data, NULL);
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
#else #else
const char *subject = s.c_str(); const char *subject = s.c_str();
int ovector[OVECCOUNT]; int ovector[OVECCOUNT];
@ -155,14 +149,18 @@ std::list<SMatch> Regex::searchAll(const std::string& s) const {
} }
} while (rc > 0); } while (rc > 0);
#ifdef WITH_PCRE2
pcre2_match_data_free(match_data);
#endif
return retList; return retList;
} }
bool Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures) const { bool Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures) const {
#ifdef WITH_PCRE2 #ifdef WITH_PCRE2
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str()); PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(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);
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); 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 #else
const char *subject = s.c_str(); const char *subject = s.c_str();
int ovector[OVECCOUNT]; int ovector[OVECCOUNT];
@ -181,6 +179,9 @@ bool Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& cap
captures.push_back(capture); captures.push_back(capture);
} }
#ifdef WITH_PCRE2
pcre2_match_data_free(match_data);
#endif
return (rc > 0); return (rc > 0);
} }
@ -190,14 +191,15 @@ bool Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captu
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str()); PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());
PCRE2_SIZE startOffset = 0; PCRE2_SIZE startOffset = 0;
pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, NULL);
while (startOffset <= s.length()) { while (startOffset <= s.length()) {
uint32_t pcre2_options = 0; uint32_t pcre2_options = 0;
if (prev_match_zero_length) { if (prev_match_zero_length) {
pcre2_options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED; pcre2_options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
} }
int rc = pcre2_match(m_pc, pcre2_s, s.length(), int rc = pcre2_match(m_pc, pcre2_s, s.length(),
startOffset, pcre2_options, m_match_data, NULL); startOffset, pcre2_options, match_data, NULL);
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
#else #else
const char *subject = s.c_str(); const char *subject = s.c_str();
@ -258,17 +260,21 @@ bool Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captu
} }
} }
#ifdef WITH_PCRE2
pcre2_match_data_free(match_data);
#endif
return (captures.size() > 0); return (captures.size() > 0);
} }
int Regex::search(const std::string& s, SMatch *match) const { int Regex::search(const std::string& s, SMatch *match) const {
#ifdef WITH_PCRE2 #ifdef WITH_PCRE2
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str()); PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(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(), 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 if (ret > 0) { // match
PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(m_match_data); PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
#else #else
int ovector[OVECCOUNT]; int ovector[OVECCOUNT];
int ret = pcre_exec(m_pc, m_pce, s.c_str(), 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); 0);
} }
#ifdef WITH_PCRE2
pcre2_match_data_free(match_data);
#endif
return ret; return ret;
} }
int Regex::search(const std::string& s) const { int Regex::search(const std::string& s) const {
#ifdef WITH_PCRE2 #ifdef WITH_PCRE2
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str()); PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(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) { if (rc > 0) {
return 1; // match return 1; // match
} else { } else {

View File

@ -85,7 +85,6 @@ class Regex {
private: private:
#if WITH_PCRE2 #if WITH_PCRE2
pcre2_code *m_pc; pcre2_code *m_pc;
pcre2_match_data *m_match_data;
#else #else
pcre *m_pc = NULL; pcre *m_pc = NULL;
pcre_extra *m_pce = NULL; pcre_extra *m_pce = NULL;