diff options
-rw-r--r-- | .github/workflows/ci-linux.yml | 3 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | data/modules.example.conf | 10 | ||||
-rw-r--r-- | modules/extra/m_regex_pcre2.cpp | 93 |
4 files changed, 105 insertions, 2 deletions
diff --git a/.github/workflows/ci-linux.yml b/.github/workflows/ci-linux.yml index 62e0cbb4e..a2c35dc40 100644 --- a/.github/workflows/ci-linux.yml +++ b/.github/workflows/ci-linux.yml @@ -22,6 +22,7 @@ jobs: libgnutls28-dev \ libldap2-dev \ libmysqlclient-dev \ + libpcre2-dev \ libpcre3-dev \ libsqlite3-dev \ libssl-dev \ @@ -29,7 +30,7 @@ jobs: make - name: Enable extras run: | - for MODULE in m_ldap.cpp m_ldap_authentication.cpp m_ldap_oper.cpp m_mysql.cpp m_regex_pcre.cpp m_regex_posix.cpp m_regex_tre.cpp m_sql_authentication.cpp m_sql_log.cpp m_sql_oper.cpp m_sqlite.cpp m_ssl_gnutls.cpp m_ssl_openssl.cpp stats + for MODULE in m_ldap.cpp m_ldap_authentication.cpp m_ldap_oper.cpp m_mysql.cpp m_regex_pcre.cpp m_regex_pcre2.cpp m_regex_posix.cpp m_regex_tre.cpp m_sql_authentication.cpp m_sql_log.cpp m_sql_oper.cpp m_sqlite.cpp m_ssl_gnutls.cpp m_ssl_openssl.cpp stats do ln -s ${{ github.workspace }}/modules/extra/$MODULE ${{ github.workspace }}/modules done diff --git a/.gitignore b/.gitignore index b2f62b5cd..03a3a02f5 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ modules/m_ldap_authentication.cpp modules/m_ldap_oper.cpp modules/m_mysql.cpp modules/m_regex_pcre.cpp +modules/m_regex_pcre2.cpp modules/m_regex_posix.cpp modules/m_regex_tre.cpp modules/m_sql_authentication.cpp diff --git a/data/modules.example.conf b/data/modules.example.conf index aae45ff12..eba8f777f 100644 --- a/data/modules.example.conf +++ b/data/modules.example.conf @@ -403,11 +403,19 @@ module { name = "help" } /* * m_regex_pcre [EXTRA] * - * Provides the regex engine regex/pcre, which uses the Perl Compatible Regular Expressions library. + * Provides the regex engine regex/pcre, which uses version 1 of the Perl Compatible Regular + * Expressions library. This can not be loaded at the same time as the m_regex_pcre2 module. */ #module { name = "m_regex_pcre" } /* + * m_regex_pcre2 [EXTRA] + * + * Provides the regex engine regex/pcre, which uses version 2 of the Perl Compatible Regular + * Expressions library. This can not be loaded at the same time as the m_regex_pcre module. +#module { name = "m_regex_pcre2" } + +/* * m_regex_posix [EXTRA] * * Provides the regex engine regex/posix, which uses the POSIX compliant regular expressions. diff --git a/modules/extra/m_regex_pcre2.cpp b/modules/extra/m_regex_pcre2.cpp new file mode 100644 index 000000000..1351d8112 --- /dev/null +++ b/modules/extra/m_regex_pcre2.cpp @@ -0,0 +1,93 @@ +/* + * + * (C) 2012-2022 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + */ + +/* RequiredLibraries: pcre2-8 */ +/* RequiredWindowsLibraries: libpcre2-8 */ + +#include "module.h" + +#define PCRE2_CODE_UNIT_WIDTH 8 +#include <pcre2.h> + +class PCRERegex : public Regex +{ + pcre2_code *regex; + + public: + PCRERegex(const Anope::string &expr) : Regex(expr) + { + int errcode; + PCRE2_SIZE erroffset; + this->regex = pcre2_compile(reinterpret_cast<PCRE2_SPTR8>(expr.c_str()), expr.length(), PCRE2_CASELESS, &errcode, &erroffset, NULL); + + if (!this->regex) + { + PCRE2_UCHAR error[128]; + pcre2_get_error_message(errcode, error, sizeof error); + throw RegexException("Error in regex " + expr + " at offset " + stringify(erroffset) + ": " + reinterpret_cast<const char*>(error)); + } + } + + ~PCRERegex() + { + pcre2_code_free(this->regex); + } + + bool Matches(const Anope::string &str) + { + pcre2_match_data *unused = pcre2_match_data_create_from_pattern(this->regex, NULL); + int result = pcre2_match(regex, reinterpret_cast<PCRE2_SPTR8>(str.c_str()), str.length(), 0, 0, unused, NULL); + pcre2_match_data_free(unused); + return result >= 0; + } +}; + +class PCRERegexProvider : public RegexProvider +{ + public: + PCRERegexProvider(Module *creator) : RegexProvider(creator, "regex/pcre") { } + + Regex *Compile(const Anope::string &expression) anope_override + { + return new PCRERegex(expression); + } +}; + +class ModuleRegexPCRE : public Module +{ + PCRERegexProvider pcre_regex_provider; + + public: + ModuleRegexPCRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), + pcre_regex_provider(this) + { + this->SetPermanent(true); + } + + ~ModuleRegexPCRE() + { + for (std::list<XLineManager *>::iterator it = XLineManager::XLineManagers.begin(); it != XLineManager::XLineManagers.end(); ++it) + { + XLineManager *xlm = *it; + const std::vector<XLine *> &xlines = xlm->GetList(); + + for (unsigned int i = 0; i < xlines.size(); ++i) + { + XLine *x = xlines[i]; + + if (x->regex && dynamic_cast<PCRERegex *>(x->regex)) + { + delete x->regex; + x->regex = NULL; + } + } + } + } +}; + +MODULE_INIT(ModuleRegexPCRE) |