diff options
author | Adam <Adam@anope.org> | 2014-04-02 13:06:48 -0400 |
---|---|---|
committer | Adam <Adam@anope.org> | 2014-04-02 13:08:14 -0400 |
commit | 52bc8e4bc799d38e92d38d497a2bd055950841bb (patch) | |
tree | b80ea985f1adffa43ca046c014e3b81f9404db8d | |
parent | ee133c03f206a7fab78a700b183fbc8684b9d6bf (diff) |
Remove regex mods, use std::regex instead
-rw-r--r-- | data/example.conf | 8 | ||||
-rw-r--r-- | data/modules.example.conf | 22 | ||||
-rw-r--r-- | include/config.h | 2 | ||||
-rw-r--r-- | include/module.h | 1 | ||||
-rw-r--r-- | include/regexpr.h | 44 | ||||
-rw-r--r-- | include/services.h | 1 | ||||
-rw-r--r-- | include/xline.h | 2 | ||||
-rw-r--r-- | modules/commands/os_akill.cpp | 19 | ||||
-rw-r--r-- | modules/commands/os_sxline.cpp | 40 | ||||
-rw-r--r-- | modules/extra/m_regex_pcre.cpp | 54 | ||||
-rw-r--r-- | modules/extra/m_regex_posix.cpp | 56 | ||||
-rw-r--r-- | modules/extra/m_regex_tre.cpp | 57 | ||||
-rw-r--r-- | modules/pseudoclients/operserv.cpp | 8 | ||||
-rw-r--r-- | src/config.cpp | 20 | ||||
-rw-r--r-- | src/misc.cpp | 34 | ||||
-rw-r--r-- | src/xline.cpp | 19 |
16 files changed, 67 insertions, 320 deletions
diff --git a/data/example.conf b/data/example.conf index e7b5627ee..a4f3ac886 100644 --- a/data/example.conf +++ b/data/example.conf @@ -515,12 +515,12 @@ options */ hideregisteredcommands = yes - /* The regex engine to use, as provided by the regex modules. - * Leave commented to disable regex matching. + /* + * The grammar regular expressions should use. Options are "ecmascript", "basic", "extended", "awk", "grep", and "egrep". * - * Note for this to work the regex module providing the regex engine must be loaded. + * This directive is optional. */ - regexengine = "regex/pcre" + regexengine = "ecmascript" /* * A list of languages to load on startup that will be available in /nickserv set language. diff --git a/data/modules.example.conf b/data/modules.example.conf index 86b83b583..b7644537d 100644 --- a/data/modules.example.conf +++ b/data/modules.example.conf @@ -366,28 +366,6 @@ module { name = "help" } } /* - * m_regex_pcre [EXTRA] - * - * Provides the regex engine regex/pcre, which uses the Perl Compatible Regular Expressions library. - */ -#module { name = "m_regex_pcre" } - -/* - * m_regex_posix [EXTRA] - * - * Provides the regex engine regex/posix, which uses the POSIX compliant regular expressions. - * This is likely the only regex module you will not need extra libraries for. - */ -#module { name = "m_regex_posix" } - -/* - * m_regex_tre [EXTRA] - * - * Provides the regex engine regex/tre, which uses the TRE regex library. - */ -#module { name = "m_regex_tre" } - -/* * m_rewrite * * Allows rewriting commands sent to/from clients. diff --git a/include/config.h b/include/config.h index ccb04ce55..903c41120 100644 --- a/include/config.h +++ b/include/config.h @@ -103,6 +103,8 @@ namespace Configuration time_t TimeoutCheck; /* options:usestrictprivmsg */ bool UseStrictPrivmsg; + /* flag for options:regexengine */ + std::regex::flag_type regex_flags; /* either "/msg " or "/" */ Anope::string StrictPrivmsg; diff --git a/include/module.h b/include/module.h index 7bfc40cfe..571cf4a6a 100644 --- a/include/module.h +++ b/include/module.h @@ -31,7 +31,6 @@ #include "modules.h" #include "opertype.h" #include "protocol.h" -#include "regexpr.h" #include "regchannel.h" #include "serialize.h" #include "servers.h" diff --git a/include/regexpr.h b/include/regexpr.h deleted file mode 100644 index d8b96d750..000000000 --- a/include/regexpr.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * - * (C) 2003-2014 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - */ - -#pragma once - -#include "services.h" -#include "anope.h" -#include "service.h" - -class RegexException : public CoreException -{ - public: - RegexException(const Anope::string &reason = "") : CoreException(reason) { } - - virtual ~RegexException() throw() { } -}; - -class CoreExport Regex -{ - Anope::string expression; - protected: - Regex(const Anope::string &expr) : expression(expr) { } - public: - virtual ~Regex() { } - const Anope::string &GetExpression() { return expression; } - virtual bool Matches(const Anope::string &str) = 0; -}; - -class CoreExport RegexProvider : public Service -{ - public: - RegexProvider(Module *o, const Anope::string &n) : Service(o, "Regex", n) { } - virtual Regex *Compile(const Anope::string &) = 0; -}; - diff --git a/include/services.h b/include/services.h index 45eb84c32..5965cea09 100644 --- a/include/services.h +++ b/include/services.h @@ -41,6 +41,7 @@ #include <set> #include <algorithm> #include <iterator> +#include <regex> #include "defs.h" diff --git a/include/xline.h b/include/xline.h index ae9a1919b..3a1a190c3 100644 --- a/include/xline.h +++ b/include/xline.h @@ -18,7 +18,7 @@ class CoreExport XLine : public Serializable void InitRegex(); public: Anope::string mask; - Regex *regex; + std::regex *regex; Anope::string by; time_t created; time_t expires; diff --git a/modules/commands/os_akill.cpp b/modules/commands/os_akill.cpp index 44c8fb23d..81dd69ed2 100644 --- a/modules/commands/os_akill.cpp +++ b/modules/commands/os_akill.cpp @@ -122,29 +122,20 @@ class CommandOSAKill : public Command if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); - - if (regexengine.empty()) + if (!Config->regex_flags) { source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", regexengine); - if (!provider) - { - source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); - return; - } - + Anope::string stripped_mask = mask.substr(1, mask.length() - 2); try { - Anope::string stripped_mask = mask.substr(1, mask.length() - 2); - delete provider->Compile(stripped_mask); + std::regex(stripped_mask.str(), Config->regex_flags); } - catch (const RegexException &ex) + catch (const std::regex_error &ex) { - source.Reply("%s", ex.GetReason().c_str()); + source.Reply("%s", ex.what()); return; } } diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp index 87d8efe5d..20b937bb0 100644 --- a/modules/commands/os_sxline.cpp +++ b/modules/commands/os_sxline.cpp @@ -317,29 +317,20 @@ class CommandOSSNLine : public CommandOSSXLineBase if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); - - if (regexengine.empty()) + if (!Config->regex_flags) { source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", regexengine); - if (!provider) - { - source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); - return; - } - + Anope::string stripped_mask = mask.substr(1, mask.length() - 2); try { - Anope::string stripped_mask = mask.substr(1, mask.length() - 2); - delete provider->Compile(stripped_mask); + std::regex(stripped_mask.str(), Config->regex_flags); } - catch (const RegexException &ex) + catch (const std::regex_error &ex) { - source.Reply("%s", ex.GetReason().c_str()); + source.Reply("%s", ex.what()); return; } } @@ -446,7 +437,7 @@ class CommandOSSNLine : public CommandOSSXLineBase "\002Note\002: because the realname mask may contain spaces, the\n" "separator between it and the reason is a colon.")); const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); - if (!regexengine.empty()) + if (Config->regex_flags && !regexengine.empty()) { source.Reply(" "); source.Reply(_("Regex matches are also supported using the %s engine.\n" @@ -531,29 +522,20 @@ class CommandOSSQLine : public CommandOSSXLineBase if (mask[0] == '/' && mask[mask.length() - 1] == '/') { - const Anope::string ®exengine = Config->GetBlock("options")->Get<const Anope::string>("regexengine"); - - if (regexengine.empty()) + if (!Config->regex_flags) { source.Reply(_("Regex is disabled.")); return; } - ServiceReference<RegexProvider> provider("Regex", regexengine); - if (!provider) - { - source.Reply(_("Unable to find regex engine %s."), regexengine.c_str()); - return; - } - + Anope::string stripped_mask = mask.substr(1, mask.length() - 2); try { - Anope::string stripped_mask = mask.substr(1, mask.length() - 2); - delete provider->Compile(stripped_mask); + std::regex(stripped_mask.str(), Config->regex_flags); } - catch (const RegexException &ex) + catch (const std::regex_error &ex) { - source.Reply("%s", ex.GetReason().c_str()); + source.Reply("%s", ex.what()); return; } } diff --git a/modules/extra/m_regex_pcre.cpp b/modules/extra/m_regex_pcre.cpp deleted file mode 100644 index a7c9d4ba8..000000000 --- a/modules/extra/m_regex_pcre.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* RequiredLibraries: pcre */ - -#include "module.h" -#include <pcre.h> - -class PCRERegex : public Regex -{ - pcre *regex; - - public: - PCRERegex(const Anope::string &expr) : Regex(expr) - { - const char *error; - int erroffset; - this->regex = pcre_compile(expr.c_str(), PCRE_CASELESS, &error, &erroffset, NULL); - if (!this->regex) - throw RegexException("Error in regex " + expr + " at offset " + stringify(erroffset) + ": " + error); - } - - ~PCRERegex() - { - pcre_free(this->regex); - } - - bool Matches(const Anope::string &str) - { - return pcre_exec(this->regex, NULL, str.c_str(), str.length(), 0, 0, NULL, 0) > -1; - } -}; - -class PCRERegexProvider : public RegexProvider -{ - public: - PCRERegexProvider(Module *creator) : RegexProvider(creator, "regex/pcre") { } - - Regex *Compile(const Anope::string &expression) 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); - } -}; - -MODULE_INIT(ModuleRegexPCRE) diff --git a/modules/extra/m_regex_posix.cpp b/modules/extra/m_regex_posix.cpp deleted file mode 100644 index 933ee59af..000000000 --- a/modules/extra/m_regex_posix.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "module.h" -#include <sys/types.h> -#include <regex.h> - -class POSIXRegex : public Regex -{ - regex_t regbuf; - - public: - POSIXRegex(const Anope::string &expr) : Regex(expr) - { - int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB); - if (err) - { - char buf[BUFSIZE]; - regerror(err, &this->regbuf, buf, sizeof(buf)); - regfree(&this->regbuf); - throw RegexException("Error in regex " + expr + ": " + buf); - } - } - - ~POSIXRegex() - { - regfree(&this->regbuf); - } - - bool Matches(const Anope::string &str) - { - return regexec(&this->regbuf, str.c_str(), 0, NULL, 0) == 0; - } -}; - -class POSIXRegexProvider : public RegexProvider -{ - public: - POSIXRegexProvider(Module *creator) : RegexProvider(creator, "regex/posix") { } - - Regex *Compile(const Anope::string &expression) override - { - return new POSIXRegex(expression); - } -}; - -class ModuleRegexPOSIX : public Module -{ - POSIXRegexProvider posix_regex_provider; - - public: - ModuleRegexPOSIX(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), - posix_regex_provider(this) - { - this->SetPermanent(true); - } -}; - -MODULE_INIT(ModuleRegexPOSIX) diff --git a/modules/extra/m_regex_tre.cpp b/modules/extra/m_regex_tre.cpp deleted file mode 100644 index 0f5c0eaf7..000000000 --- a/modules/extra/m_regex_tre.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* RequiredLibraries: tre */ - -#include "module.h" -#include <tre/regex.h> - -class TRERegex : public Regex -{ - regex_t regbuf; - - public: - TRERegex(const Anope::string &expr) : Regex(expr) - { - int err = regcomp(&this->regbuf, expr.c_str(), REG_EXTENDED | REG_NOSUB); - if (err) - { - char buf[BUFSIZE]; - regerror(err, &this->regbuf, buf, sizeof(buf)); - regfree(&this->regbuf); - throw RegexException("Error in regex " + expr + ": " + buf); - } - } - - ~TRERegex() - { - regfree(&this->regbuf); - } - - bool Matches(const Anope::string &str) - { - return regexec(&this->regbuf, str.c_str(), 0, NULL, 0) == 0; - } -}; - -class TRERegexProvider : public RegexProvider -{ - public: - TRERegexProvider(Module *creator) : RegexProvider(creator, "regex/tre") { } - - Regex *Compile(const Anope::string &expression) override - { - return new TRERegex(expression); - } -}; - -class ModuleRegexTRE : public Module -{ - TRERegexProvider tre_regex_provider; - - public: - ModuleRegexTRE(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR), - tre_regex_provider(this) - { - this->SetPermanent(true); - } -}; - -MODULE_INIT(ModuleRegexTRE) diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp index 885cfcc85..7b43436f7 100644 --- a/modules/pseudoclients/operserv.cpp +++ b/modules/pseudoclients/operserv.cpp @@ -41,7 +41,7 @@ class SGLineManager : public XLineManager if (x->regex) { Anope::string uh = u->GetIdent() + "@" + u->host, nuhr = u->nick + "!" + uh + "#" + u->realname; - return x->regex->Matches(uh) || x->regex->Matches(nuhr); + return std::regex_match(uh.str(), *x->regex) || std::regex_match(nuhr.str(), *x->regex); } if (!x->GetNick().empty() && !Anope::Match(u->nick, x->GetNick())) @@ -111,7 +111,7 @@ class SQLineManager : public XLineManager bool Check(User *u, const XLine *x) override { if (x->regex) - return x->regex->Matches(u->nick); + return std::regex_match(u->nick.c_str(), *x->regex); return Anope::Match(u->nick, x->mask); } @@ -122,7 +122,7 @@ class SQLineManager : public XLineManager XLine *x = *it; if (x->regex) { - if (x->regex->Matches(c->name)) + if (std::regex_match(c->name.str(), *x->regex)) return x; } else if (Anope::Match(c->name, x->mask, false, true)) @@ -165,7 +165,7 @@ class SNLineManager : public XLineManager bool Check(User *u, const XLine *x) override { if (x->regex) - return x->regex->Matches(u->realname); + return std::regex_match(u->realname.str(), *x->regex); return Anope::Match(u->realname, x->mask, false, true); } }; diff --git a/src/config.cpp b/src/config.cpp index 0275cb7f8..6473cf830 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -115,6 +115,7 @@ Conf::Conf() : Block("") { ReadTimeout = 0; UsePrivmsg = DefPrivmsg = false; + regex_flags = 0; this->LoadConf(ServicesConf); @@ -526,6 +527,25 @@ Conf::Conf() : Block("") if (!options->Get<unsigned>("seed")) Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!"; + /* check regexengine */ + const Anope::string ®ex_engine = options->Get<Anope::string>("regexengine"); + if (regex_engine == "ecmascript") + regex_flags = std::regex::ECMAScript; + else if (regex_engine == "basic") + regex_flags = std::regex::basic; + else if (regex_engine == "extended") + regex_flags = std::regex::extended; + else if (regex_engine == "awk") + regex_flags = std::regex::awk; + else if (regex_engine == "grep") + regex_flags = std::regex::grep; + else if (regex_engine == "egrep") + regex_flags = std::regex::egrep; + /* always enable icase and optimize */ + if (regex_flags) + regex_flags |= std::regex::icase | std::regex::optimize; + + /* apply changes from an older config? */ if (Config) { /* Apply module chnages */ diff --git a/src/misc.cpp b/src/misc.cpp index 57314c53b..ee7724941 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -17,7 +17,6 @@ #include "config.h" #include "bots.h" #include "language.h" -#include "regexpr.h" #include "sockets.h" #include <errno.h> @@ -408,38 +407,29 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case { size_t s = 0, m = 0, str_len = str.length(), mask_len = mask.length(); - if (use_regex && mask_len >= 2 && mask[0] == '/' && mask[mask.length() - 1] == '/') + if (use_regex && Config->regex_flags && mask_len >= 2 && mask[0] == '/' && mask[mask.length() - 1] == '/') { Anope::string stripped_mask = mask.substr(1, mask_len - 2); // This is often called with the same mask multiple times in a row, so cache it - static Regex *r = NULL; + static Anope::string pattern; + static std::regex r; - if (r == NULL || r->GetExpression() != stripped_mask) + if (pattern != stripped_mask) { - ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string>("regexengine")); - if (provider) + try { - try - { - delete r; - r = NULL; - // This may throw - r = provider->Compile(stripped_mask); - } - catch (const RegexException &ex) - { - Log(LOG_DEBUG) << ex.GetReason(); - } + r.assign(stripped_mask.str(), Config->regex_flags); + pattern = stripped_mask; } - else + catch (const std::regex_error &error) { - delete r; - r = NULL; + Log(LOG_DEBUG) << error.what(); } } - if (r != NULL && r->Matches(str)) - return true; + if (pattern == stripped_mask) + if (std::regex_search(str.str(), r)) + return true; // Fall through to non regex match } diff --git a/src/xline.cpp b/src/xline.cpp index ea74ba8c7..8c8f6034c 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -15,7 +15,6 @@ #include "xline.h" #include "users.h" #include "sockets.h" -#include "regexpr.h" #include "config.h" #include "commands.h" #include "servers.h" @@ -26,21 +25,17 @@ Serialize::Checker<std::multimap<Anope::string, XLine *, ci::less> > XLineManage void XLine::InitRegex() { - if (this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/' && !Config->GetBlock("options")->Get<const Anope::string>("regexengine").empty()) + if (this->mask.length() >= 2 && this->mask[0] == '/' && this->mask[this->mask.length() - 1] == '/' && Config->regex_flags) { Anope::string stripped_mask = this->mask.substr(1, this->mask.length() - 2); - ServiceReference<RegexProvider> provider("Regex", Config->GetBlock("options")->Get<const Anope::string>("regexengine")); - if (provider) + try { - try - { - this->regex = provider->Compile(stripped_mask); - } - catch (const RegexException &ex) - { - Log(LOG_DEBUG) << ex.GetReason(); - } + this->regex = new std::regex(stripped_mask.str(), Config->regex_flags); + } + catch (const std::regex_error &ex) + { + Log(LOG_DEBUG) << ex.what(); } } } |