summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/example.conf8
-rw-r--r--data/modules.example.conf22
-rw-r--r--include/config.h2
-rw-r--r--include/module.h1
-rw-r--r--include/regexpr.h44
-rw-r--r--include/services.h1
-rw-r--r--include/xline.h2
-rw-r--r--modules/commands/os_akill.cpp19
-rw-r--r--modules/commands/os_sxline.cpp40
-rw-r--r--modules/extra/m_regex_pcre.cpp54
-rw-r--r--modules/extra/m_regex_posix.cpp56
-rw-r--r--modules/extra/m_regex_tre.cpp57
-rw-r--r--modules/pseudoclients/operserv.cpp8
-rw-r--r--src/config.cpp20
-rw-r--r--src/misc.cpp34
-rw-r--r--src/xline.cpp19
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 &regexengine = 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 &regexengine = 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 &regexengine = 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 &regexengine = 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 &regex_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();
}
}
}