perf. improvement/rx: Only compute dynamic regex in case of macro

On #1528 was added the support for macro expansion on @rx operator.
The performance improvement suggested on the pull request was not
thread safe, therefore removed. This patch adds a performance
improvement on top of #1528. The benchmarks points to 10x faster
results on OWASP CRS.
This commit is contained in:
Felipe Zimmerle
2018-01-02 20:54:44 -03:00
parent 4a23891c85
commit 768a76a61e
8 changed files with 56 additions and 34 deletions

View File

@@ -28,6 +28,15 @@ namespace modsecurity {
namespace operators {
bool Rx::init(const std::string &arg, std::string *error) {
m_containsMacro = MacroExpansion::containsMacro(m_param);
if (m_containsMacro == false) {
m_re = new Regex(m_param);
}
return true;
}
bool Rx::evaluate(Transaction *transaction, Rule *rule,
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
@@ -39,8 +48,12 @@ bool Rx::evaluate(Transaction *transaction, Rule *rule,
return true;
}
std::string eparam = MacroExpansion::expand(m_param, transaction);
re = new Regex(eparam);
if (m_containsMacro) {
std::string eparam = MacroExpansion::expand(m_param, transaction);
re = new Regex(eparam);
} else {
re = m_re;
}
matches = re->searchAll(input);
if (rule && rule->getActionsByName("capture").size() > 0 && transaction) {
@@ -62,7 +75,9 @@ bool Rx::evaluate(Transaction *transaction, Rule *rule,
logOffset(ruleMessage, i.m_offset, i.m_length);
}
delete re;
if (m_containsMacro) {
delete re;
}
if (matches.size() > 0) {
return true;

View File

@@ -36,17 +36,25 @@ class Rx : public Operator {
public:
/** @ingroup ModSecurity_Operator */
Rx(std::string op, std::string param, bool negation)
: Operator(op, param, negation) {
: Operator(op, param, negation),
m_containsMacro(false) {
}
Rx(std::string name, std::string param)
: Operator(name, param) {
: Operator(name, param),
m_containsMacro(false) {
}
explicit Rx(std::string param)
: Operator("Rx", param) {
: Operator("Rx", param),
m_containsMacro(false) {
}
~Rx() {
if (m_containsMacro == false && m_re != NULL) {
delete m_re;
m_re = NULL;
}
}
bool evaluate(Transaction *transaction, Rule *rule,
const std::string &input) override {
return evaluate(transaction, NULL, input, NULL);
@@ -58,6 +66,11 @@ class Rx : public Operator {
bool evaluate(Transaction *transaction, Rule *rule,
const std::string& input,
std::shared_ptr<RuleMessage> ruleMessage) override;
bool init(const std::string &arg, std::string *error);
private:
bool m_containsMacro;
Regex *m_re;
};