Refactor build system to use libpcre2 as the default

Updated the build system and related source files to use libpcre2 as the
default regex library instead of the deprecated libpcre. This change
ensures future compatibility and aligns with the library's maintenance status.

To build with the old libpcre, the `--with-pcre` configuration parameter
can be specified.
This commit is contained in:
Gabor Berkes 2024-12-10 10:16:14 +00:00
parent 4fb22466a0
commit c6433df7b2
8 changed files with 51 additions and 54 deletions

View File

@ -26,7 +26,7 @@ jobs:
- {label: "wo geoip", opt: "--without-geoip" }
- {label: "wo ssdeep", opt: "--without-ssdeep" }
- {label: "with lmdb", opt: "--with-lmdb" }
- {label: "with pcre2", opt: "--with-pcre2" }
- {label: "with pcre", opt: "--with-pcre" }
exclude:
- platform: {label: "x32"}
configure: {label: "wo geoip"}
@ -88,7 +88,7 @@ jobs:
- {label: "wo geoip", opt: "--without-geoip" }
- {label: "wo ssdeep", opt: "--without-ssdeep" }
- {label: "with lmdb", opt: "--with-lmdb" }
- {label: "with pcre2", opt: "--with-pcre2" }
- {label: "with pcre", opt: "--with-pcre" }
steps:
- name: Setup Dependencies
# curl, pcre2 not installed because they're already

View File

@ -21,8 +21,8 @@ AC_ARG_WITH(
[test_paths="${with_pcre}"],
[test_paths="/usr/local/libpcre /usr/local/pcre /usr/local /opt/libpcre /opt/pcre /opt /usr /opt/local"])
if test "x${with_pcre2}" != "x" && test "x${with_pcre2}" != "xno"; then
AC_MSG_NOTICE([pcre2 specified; omitting check for pcre])
if test "x${with_pcre}" == "x" && test "x${with_pcre}" != "xno"; then
AC_MSG_NOTICE([Support for pcre not requested; omitting check for pcre])
else
AC_MSG_CHECKING([for libpcre config script])
@ -106,6 +106,7 @@ else
LIBS=$save_LIBS
fi
PCRE_CFLAGS="-DWITH_PCRE$ {PCRE_CFLAGS}"
AC_SUBST(PCRE_CONFIG)
AC_SUBST(PCRE_VERSION)
AC_SUBST(PCRE_CPPFLAGS)

View File

@ -91,21 +91,16 @@ if test -z "${PCRE2_LDADD}"; then
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
PCRE2_FOUND=1
AC_MSG_NOTICE([using PCRE2 v${PCRE2_VERSION}])
PCRE2_CFLAGS="${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

View File

@ -141,15 +141,16 @@ CHECK_LIBXML2
#
# Check for libpcre
# Check for libpcre only if explicitly requested
#
CHECK_PCRE
#
# Check for pcre2
#
PROG_PCRE2
if test "x${with_pcre}" != "x" && test "x${with_pcre}" != "xno"; then
CHECK_PCRE
else
#
# Check for pcre2
#
PROG_PCRE2
fi
# Checks for header files.

View File

@ -21,7 +21,7 @@
#include "src/operators/operator.h"
#ifndef WITH_PCRE2
#ifdef WITH_PCRE
#if PCRE_HAVE_JIT
#define pcre_study_opt PCRE_STUDY_JIT_COMPILE
#else
@ -34,7 +34,7 @@ namespace modsecurity {
namespace operators {
VerifyCC::~VerifyCC() {
#if WITH_PCRE2
#ifndef WITH_PCRE
pcre2_code_free(m_pc);
#else
if (m_pc != NULL) {
@ -94,7 +94,7 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) {
bool VerifyCC::init(const std::string &param2, std::string *error) {
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
PCRE2_SPTR pcre2_pattern = reinterpret_cast<PCRE2_SPTR>(m_param.c_str());
uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE);
int errornumber = 0;
@ -136,7 +136,7 @@ bool VerifyCC::init(const std::string &param2, std::string *error) {
bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,
const std::string& i, RuleMessage &ruleMessage) {
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
PCRE2_SIZE offset = 0;
size_t target_length = i.length();
PCRE2_SPTR pcre2_i = reinterpret_cast<PCRE2_SPTR>(i.c_str());
@ -192,7 +192,7 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,
"\" at " + i + ". [offset " +
std::to_string(offset) + "]");
}
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre2_match_data_free(match_data);
#endif
return true;
@ -200,7 +200,7 @@ bool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,
}
}
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre2_match_data_free(match_data);
#endif

View File

@ -16,7 +16,7 @@
#ifndef SRC_OPERATORS_VERIFY_CC_H_
#define SRC_OPERATORS_VERIFY_CC_H_
#if WITH_PCRE2
#ifndef WITH_PCRE
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
#else
@ -38,7 +38,7 @@ class VerifyCC : public Operator {
/** @ingroup ModSecurity_Operator */
explicit VerifyCC(std::unique_ptr<RunTimeString> param)
: Operator("VerifyCC", std::move(param)),
#if WITH_PCRE2
#ifndef WITH_PCRE
m_pc(NULL),
m_pcje(PCRE2_ERROR_JIT_BADOPTION) { }
#else
@ -52,7 +52,7 @@ class VerifyCC : public Operator {
RuleMessage &ruleMessage) override;
bool init(const std::string &param, std::string *error) override;
private:
#if WITH_PCRE2
#ifndef WITH_PCRE
pcre2_code *m_pc;
int m_pcje;
#else

View File

@ -23,7 +23,7 @@
#include "src/utils/geo_lookup.h"
#ifndef WITH_PCRE2
#ifdef WITH_PCRE
#if PCRE_HAVE_JIT
// NOTE: Add PCRE_STUDY_EXTRA_NEEDED so studying always yields a pcre_extra strucure
// and we can selectively override match limits using a copy of that structure at runtime.
@ -35,7 +35,7 @@
#endif
#endif
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
class Pcre2MatchContextPtr {
public:
Pcre2MatchContextPtr()
@ -62,7 +62,7 @@ namespace Utils {
// Helper function to tell us if the current config indicates CRLF is a valid newline sequence
bool crlfIsNewline() {
#if WITH_PCRE2
#ifndef WITH_PCRE
uint32_t newline = 0;
pcre2_config(PCRE2_CONFIG_NEWLINE, &newline);
bool crlf_is_newline =
@ -89,7 +89,7 @@ bool crlfIsNewline() {
Regex::Regex(const std::string& pattern_, bool ignoreCase)
: pattern(pattern_.empty() ? ".*" : pattern_) {
#if WITH_PCRE2
#ifndef WITH_PCRE
PCRE2_SPTR pcre2_pattern = reinterpret_cast<PCRE2_SPTR>(pattern.c_str());
uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE);
if (ignoreCase) {
@ -117,7 +117,7 @@ Regex::Regex(const std::string& pattern_, bool ignoreCase)
Regex::~Regex() {
#if WITH_PCRE2
#ifndef WITH_PCRE
pcre2_code_free(m_pc);
#else
if (m_pc != NULL) {
@ -139,7 +139,7 @@ Regex::~Regex() {
std::list<SMatch> Regex::searchAll(const std::string& s) const {
std::list<SMatch> retList;
int rc = 0;
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());
PCRE2_SIZE offset = 0;
@ -183,14 +183,14 @@ std::list<SMatch> Regex::searchAll(const std::string& s) const {
}
} while (rc > 0);
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre2_match_data_free(match_data);
#endif
return retList;
}
RegexResult Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit) const {
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
Pcre2MatchContextPtr match_context;
if (match_limit > 0) {
// TODO: What if setting the match limit fails?
@ -235,7 +235,7 @@ RegexResult Regex::searchOneMatch(const std::string& s, std::vector<SMatchCaptur
captures.push_back(capture);
}
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre2_match_data_free(match_data);
#endif
return to_regex_result(rc);
@ -243,7 +243,7 @@ RegexResult Regex::searchOneMatch(const std::string& s, std::vector<SMatchCaptur
RegexResult Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit) const {
bool prev_match_zero_length = false;
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
Pcre2MatchContextPtr match_context;
if (match_limit > 0) {
// TODO: What if setting the match limit fails?
@ -337,14 +337,14 @@ RegexResult Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>
}
}
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre2_match_data_free(match_data);
#endif
return RegexResult::Ok;
}
int Regex::search(const std::string& s, SMatch *match) const {
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
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 = 0;
@ -371,14 +371,14 @@ int Regex::search(const std::string& s, SMatch *match) const {
0);
}
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre2_match_data_free(match_data);
#endif
return ret;
}
int Regex::search(const std::string& s) const {
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
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 rc = 0;
@ -405,7 +405,7 @@ int Regex::search(const std::string& s) const {
RegexResult Regex::to_regex_result(int pcre_exec_result) const {
if (
pcre_exec_result > 0 ||
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre_exec_result == PCRE2_ERROR_NOMATCH
#else
pcre_exec_result == PCRE_ERROR_NOMATCH
@ -413,7 +413,7 @@ RegexResult Regex::to_regex_result(int pcre_exec_result) const {
) {
return RegexResult::Ok;
} else if(
#ifdef WITH_PCRE2
#ifndef WITH_PCRE
pcre_exec_result == PCRE2_ERROR_MATCHLIMIT
#else
pcre_exec_result == PCRE_ERROR_MATCHLIMIT

View File

@ -12,7 +12,7 @@
* directly using the email address security@modsecurity.org.
*
*/
#if WITH_PCRE2
#ifndef WITH_PCRE
#define PCRE2_CODE_UNIT_WIDTH 8
#include <pcre2.h>
#else
@ -91,7 +91,7 @@ class Regex {
private:
RegexResult to_regex_result(int pcre_exec_result) const;
#if WITH_PCRE2
#ifndef WITH_PCRE
pcre2_code *m_pc;
int m_pcje;
#else