regex: Organizes the classes per file

moves Pcre to backends/pcre.cc
moves PegexMatch to regex_match.h
This commit is contained in:
Felipe Zimmerle
2019-01-18 18:42:15 -03:00
parent 686b6ffff7
commit a5ee59f5d0
6 changed files with 214 additions and 148 deletions

View File

@@ -23,6 +23,16 @@ AC_ARG_WITH(
AC_MSG_CHECKING([for libpcre config script])
if test "x${with_pcre}" == "xno"; then
AC_MSG_NOTICE([Support for PCRE was disabled by the utilization of --without-pcre or --with-pcre=no])
PCRE_DISABLED=yes
else
if test "x${with_pcre}" == "xyes"; then
PCRE_MANDATORY=yes
AC_MSG_NOTICE([PCRE support was marked as mandatory by the utilization of --with-pcre=yes])
test_paths="/usr/local/libpcre /usr/local/pcre /usr/local /opt/libpcre /opt/pcre /opt /usr /opt/local"
fi
for x in ${test_paths}; do
dnl # Determine if the script was specified and use it directly
if test ! -d "$x" -a -e "$x"; then
@@ -55,7 +65,7 @@ if test -n "${pcre_path}"; then
AC_MSG_RESULT([${PCRE_CONFIG}])
PCRE_VERSION="`${PCRE_CONFIG} --version`"
if test ! -z "${PCRE_VERSION}"; then AC_MSG_NOTICE(pcre VERSION: $PCRE_VERSION); fi
PCRE_CFLAGS="`${PCRE_CONFIG} --cflags`"
PCRE_CFLAGS="`${PCRE_CONFIG} --cflags` -DWITH_PCRE"
if test ! -z "${PCRE_CFLAGS}"; then AC_MSG_NOTICE(pcre CFLAGS: $PCRE_CFLAGS); fi
PCRE_LDADD="`${PCRE_CONFIG} --libs`"
if test ! -z "${PCRE_LDADD}"; then AC_MSG_NOTICE(pcre LDADD: $PCRE_LDADD); fi
@@ -90,20 +100,31 @@ if test -n "${PCRE_VERSION}"; then
LDFLAGS=$save_$LDFLAGS
fi
AC_SUBST(PCRE_CONFIG)
AC_SUBST(PCRE_VERSION)
AC_SUBST(PCRE_CPPFLAGS)
AC_SUBST(PCRE_CFLAGS)
AC_SUBST(PCRE_LDFLAGS)
AC_SUBST(PCRE_LDADD)
AC_SUBST(PCRE_LD_PATH)
if test -z "${PCRE_VERSION}"; then
AC_MSG_NOTICE([*** pcre library not found.])
ifelse([$2], , AC_MSG_ERROR([pcre library is required]), $2)
else
AC_MSG_NOTICE([using pcre v${PCRE_VERSION}])
ifelse([$1], , , $1)
PCRE_LDADD="${PCRE_LDADD} -lpcre"
fi
if test -z "${PCRE_LDADD}"; then
if test -z "${PCRE_MANDATORY}"; then
if test -z "${PCRE_DISABLED}"; then
PCRE_FOUND=0
else
PCRE_FOUND=2
fi
else
AC_MSG_ERROR([PCRE was explicitly referenced but it was not found])
PCRE_FOUND=-1
fi
else
PCRE_FOUND=1
AC_SUBST(PCRE_CONFIG)
AC_SUBST(PCRE_VERSION)
AC_SUBST(PCRE_CPPFLAGS)
AC_SUBST(PCRE_CFLAGS)
AC_SUBST(PCRE_LDFLAGS)
AC_SUBST(PCRE_LDADD)
AC_SUBST(PCRE_LD_PATH)
PCRE_DISPLAY="${PCRE_LDADD}, ${PCRE_CFLAGS}"
AC_SUBST(PCRE_DISPLAY)
fi
])

View File

@@ -13,23 +13,114 @@
*
*/
#include <pcre.h>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include <pcre.h>
#include "src/regex/backend/pcre.h"
#include "src/regex/regex_match.h"
#ifndef SRC_REGEX_BACKEND_PCRE_H_
#define SRC_REGEX_BACKEND_PCRE_H_
namespace modsecurity {
namespace regex {
namespace backend {
#if PCRE_HAVE_JIT
#define pcre_study_opt PCRE_STUDY_JIT_COMPILE
#else
#define pcre_study_opt 0
#endif
Pcre::Pcre(const std::string& pattern_)
: pattern(pattern_.empty() ? ".*" : pattern_) {
const char *errptr = NULL;
int erroffset;
m_pc = pcre_compile(pattern.c_str(), PCRE_DOTALL|PCRE_MULTILINE,
&errptr, &erroffset, NULL);
m_pce = pcre_study(m_pc, pcre_study_opt, &errptr);
}
Pcre::~Pcre() {
if (m_pc != NULL) {
pcre_free(m_pc);
m_pc = NULL;
}
if (m_pce != NULL) {
#if PCRE_HAVE_JIT
pcre_free_study(m_pce);
#else
pcre_free(m_pce);
#endif
m_pce = NULL;
}
}
std::list<RegexMatch> Pcre::searchAll(const std::string& s) const {
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<RegexMatch> retList;
do {
rc = pcre_exec(m_pc, m_pce, subject,
s.size(), offset, 0, ovector, OVECCOUNT);
for (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;
break;
}
std::string match = std::string(tmpString, start, len);
offset = start + len;
retList.push_front(RegexMatch(match, start));
if (len == 0) {
rc = 0;
break;
}
}
} while (rc > 0);
return retList;
}
int Pcre::search(const std::string& s, RegexMatch *match) const {
int ovector[OVECCOUNT];
int ret = pcre_exec(m_pc, m_pce, s.c_str(),
s.size(), 0, 0, ovector, OVECCOUNT) > 0;
if (ret > 0) {
*match = RegexMatch(
std::string(s, ovector[ret-1], ovector[ret] - ovector[ret-1]),
0);
}
return ret;
}
int Pcre::search(const std::string& s) const {
int ovector[OVECCOUNT];
return pcre_exec(m_pc, m_pce, s.c_str(),
s.size(), 0, 0, ovector, OVECCOUNT) > 0;
}
} // namespace backend
} // namespace regex
} // namespace modsecurity
#endif // SRC_REGEX_BACKEND_PCRE_H_

View File

@@ -20,14 +20,40 @@
#include <string>
#include <list>
#include "src/regex/regex_match.h"
#ifndef SRC_REGEX_BACKEND_PCRE_H_
#define SRC_REGEX_BACKEND_PCRE_H_
namespace modsecurity {
namespace regex {
namespace backend {
#define OVECCOUNT 30
class Pcre {
public:
explicit Pcre(const std::string& pattern_);
~Pcre();
// m_pc and m_pce can't be easily copied
Pcre(const Pcre&) = delete;
Pcre& operator=(const Pcre&) = delete;
std::list<RegexMatch> searchAll(const std::string& s) const;
int search(const std::string &s, RegexMatch *m) const;
int search(const std::string &s) const;
const std::string pattern;
private:
pcre *m_pc = NULL;
pcre_extra *m_pce = NULL;
};
} // namespace backend
} // namespace regex
} // namespace modsecurity

View File

@@ -26,98 +26,10 @@
#include <fstream>
#include <iostream>
#include "src/utils/geo_lookup.h"
#if PCRE_HAVE_JIT
#define pcre_study_opt PCRE_STUDY_JIT_COMPILE
#else
#define pcre_study_opt 0
#endif
namespace modsecurity {
namespace regex {
Regex::Regex(const std::string& pattern_)
: pattern(pattern_.empty() ? ".*" : pattern_) {
const char *errptr = NULL;
int erroffset;
m_pc = pcre_compile(pattern.c_str(), PCRE_DOTALL|PCRE_MULTILINE,
&errptr, &erroffset, NULL);
m_pce = pcre_study(m_pc, pcre_study_opt, &errptr);
}
Regex::~Regex() {
if (m_pc != NULL) {
pcre_free(m_pc);
m_pc = NULL;
}
if (m_pce != NULL) {
#if PCRE_HAVE_JIT
pcre_free_study(m_pce);
#else
pcre_free(m_pce);
#endif
m_pce = NULL;
}
}
std::list<RegexMatch> Regex::searchAll(const std::string& s) const {
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<RegexMatch> retList;
do {
rc = pcre_exec(m_pc, m_pce, subject,
s.size(), offset, 0, ovector, OVECCOUNT);
for (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;
break;
}
std::string match = std::string(tmpString, start, len);
offset = start + len;
retList.push_front(RegexMatch(match, start));
if (len == 0) {
rc = 0;
break;
}
}
} while (rc > 0);
return retList;
}
int Regex::search(const std::string& s, RegexMatch *match) const {
int ovector[OVECCOUNT];
int ret = pcre_exec(m_pc, m_pce, s.c_str(),
s.size(), 0, 0, ovector, OVECCOUNT) > 0;
if (ret > 0) {
*match = RegexMatch(
std::string(s, ovector[ret-1], ovector[ret] - ovector[ret-1]),
0);
}
return ret;
}
int Regex::search(const std::string& s) const {
int ovector[OVECCOUNT];
return pcre_exec(m_pc, m_pce, s.c_str(),
s.size(), 0, 0, ovector, OVECCOUNT) > 0;
}
} // namespace regex
} // namespace modsecurity

View File

@@ -13,13 +13,16 @@
*
*/
#include <pcre.h>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include "src/regex/backend/pcre.h"
#include "src/regex/regex_match.h"
#ifndef SRC_REGEX_REGEX_H_
#define SRC_REGEX_REGEX_H_
@@ -27,48 +30,15 @@
namespace modsecurity {
namespace regex {
using selectedBackend = backend::Pcre;
#define OVECCOUNT 30
class RegexMatch {
public:
RegexMatch() :
m_match(),
m_offset(0) { }
RegexMatch(const std::string &match, size_t offset) :
m_match(match),
m_offset(offset) { }
const std::string& str() const { return m_match; }
size_t offset() const { return m_offset; }
private:
std::string m_match;
size_t m_offset;
class Regex : public selectedBackend {
public:
explicit Regex(const std::string& pattern) :
selectedBackend(pattern) { };
~Regex() { };
};
class Regex {
public:
explicit Regex(const std::string& pattern_);
~Regex();
// m_pc and m_pce can't be easily copied
Regex(const Regex&) = delete;
Regex& operator=(const Regex&) = delete;
std::list<RegexMatch> searchAll(const std::string& s) const;
int search(const std::string &s, RegexMatch *m) const;
int search(const std::string &s) const;
const std::string pattern;
private:
pcre *m_pc = NULL;
pcre_extra *m_pce = NULL;
};
} // namespace regex
} // namespace modsecurity

46
src/regex/regex_match.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* If any of the files related to licensing are missing or if you have any
* other questions related to licensing please contact Trustwave Holdings, Inc.
* directly using the email address security@modsecurity.org.
*
*/
#ifndef SRC_REGEX_REGEX_MATCH_H_
#define SRC_REGEX_REGEX_MATCH_H_
namespace modsecurity {
namespace regex {
class RegexMatch {
public:
RegexMatch() :
m_match(),
m_offset(0) { }
RegexMatch(const std::string &match, size_t offset) :
m_match(match),
m_offset(offset) { }
const std::string& str() const { return m_match; }
size_t offset() const { return m_offset; }
private:
std::string m_match;
size_t m_offset;
};
} // namespace regex
} // namespace modsecurity
#endif // SRC_REGEX_REGEX_MATCH_H_