Use std::shared_ptr for variable resolution

AnchoredSetVariable::resolve is called for every rule
(see RuleWithOperator::evaluate). The previous implementation allocated
a new copy of every variable, which quickly added up. In my tests,
AnchoredSetVariable::resolve function consumed 7.8% of run time.

AnchoredSetVariable (which is a multimap) values are never changed,
only added. This means it's safe to store them in std::shared_ptr,
and make resolve return shared_ptr pointing to the same object.

Other resolve implementation could also use this optimization by not
allocating new objects, however, they are not hot spots, so this
optimization was not implemented there.

In my benchmark, this raises performance from 117 requests per second to
131 RPS, and overhead is lowered from 7.8% to 2.4%.

As a bonus, replacing plain pointer with smart pointers make code
cleaner, since using smart pointers makes manual deletes no longer necessary.

Additionally, VariableOrigin is now stored in plain std::vector,
since it's wasteful to store structure containing just two integer
values using std::list<std::unique_ptr<T>>.
This commit is contained in:
WGH 2020-07-28 18:46:03 +03:00 committed by Felipe Zimmerle
parent b32182940d
commit 47be22e62a
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
55 changed files with 264 additions and 375 deletions

View File

@ -72,10 +72,9 @@ struct MyHash{
class AnchoredSetVariable : public std::unordered_multimap<std::string, class AnchoredSetVariable : public std::unordered_multimap<std::string,
VariableValue *, MyHash, MyEqual> { std::shared_ptr<const VariableValue>, MyHash, MyEqual> {
public: public:
AnchoredSetVariable(Transaction *t, const std::string &name); AnchoredSetVariable(Transaction *t, const std::string &name);
~AnchoredSetVariable();
void unset(); void unset();
@ -93,18 +92,18 @@ class AnchoredSetVariable : public std::unordered_multimap<std::string,
void setCopy(std::string key, std::string value, size_t offset); void setCopy(std::string key, std::string value, size_t offset);
void resolve(std::vector<const VariableValue *> *l); void resolve(std::vector<std::shared_ptr<const VariableValue>> *l);
void resolve(std::vector<const VariableValue *> *l, void resolve(std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke); variables::KeyExclusions &ke);
void resolve(const std::string &key, void resolve(const std::string &key,
std::vector<const VariableValue *> *l); std::vector<std::shared_ptr<const VariableValue>> *l);
void resolveRegularExpression(Utils::Regex *r, void resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l); std::vector<std::shared_ptr<const VariableValue>> *l);
void resolveRegularExpression(Utils::Regex *r, void resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke); variables::KeyExclusions &ke);
std::unique_ptr<std::string> resolveFirst(const std::string &key); std::unique_ptr<std::string> resolveFirst(const std::string &key);

View File

@ -59,8 +59,6 @@ class AnchoredVariable {
m_var(a.m_var) { } m_var(a.m_var) { }
*/ */
~AnchoredVariable();
void unset(); void unset();
void set(const std::string &a, size_t offset); void set(const std::string &a, size_t offset);
void set(const bpstd::string_view &a, size_t offset); void set(const bpstd::string_view &a, size_t offset);
@ -71,7 +69,7 @@ class AnchoredVariable {
void append(const std::string &a, size_t offset, void append(const std::string &a, size_t offset,
bool spaceSeparator, int size); bool spaceSeparator, int size);
void evaluate(std::vector<const VariableValue *> *l); void evaluate(std::vector<std::shared_ptr<const VariableValue>> *l);
std::string * evaluate(); std::string * evaluate();
std::unique_ptr<std::string> resolveFirst(); std::unique_ptr<std::string> resolveFirst();
@ -81,7 +79,7 @@ class AnchoredVariable {
std::string m_value; std::string m_value;
private: private:
VariableValue *m_var; VariableValue m_var;
}; };
} // namespace modsecurity } // namespace modsecurity

View File

@ -60,12 +60,12 @@ class Collection {
const std::string& var) = 0; const std::string& var) = 0;
virtual void resolveSingleMatch(const std::string& var, virtual void resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) = 0; std::vector<std::shared_ptr<const VariableValue>> *l) = 0;
virtual void resolveMultiMatches(const std::string& var, virtual void resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) = 0; variables::KeyExclusions &ke) = 0;
virtual void resolveRegularExpression(const std::string& var, virtual void resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) = 0; variables::KeyExclusions &ke) = 0;
@ -146,7 +146,7 @@ class Collection {
/* resolveSingleMatch */ /* resolveSingleMatch */
virtual void resolveSingleMatch(const std::string& var, virtual void resolveSingleMatch(const std::string& var,
std::string compartment, std::vector<const VariableValue *> *l) { std::string compartment, std::vector<std::shared_ptr<const VariableValue>> *l) {
std::string nkey = compartment + "::" + var; std::string nkey = compartment + "::" + var;
resolveSingleMatch(nkey, l); resolveSingleMatch(nkey, l);
} }
@ -154,7 +154,7 @@ class Collection {
virtual void resolveSingleMatch(const std::string& var, virtual void resolveSingleMatch(const std::string& var,
std::string compartment, std::string compartment2, std::string compartment, std::string compartment2,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
std::string nkey = compartment + "::" + compartment2 + "::" + var; std::string nkey = compartment + "::" + compartment2 + "::" + var;
resolveSingleMatch(nkey, l); resolveSingleMatch(nkey, l);
} }
@ -162,7 +162,7 @@ class Collection {
/* resolveMultiMatches */ /* resolveMultiMatches */
virtual void resolveMultiMatches(const std::string& var, virtual void resolveMultiMatches(const std::string& var,
std::string compartment, std::vector<const VariableValue *> *l, std::string compartment, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + var; std::string nkey = compartment + "::" + var;
resolveMultiMatches(nkey, l, ke); resolveMultiMatches(nkey, l, ke);
@ -171,7 +171,7 @@ class Collection {
virtual void resolveMultiMatches(const std::string& var, virtual void resolveMultiMatches(const std::string& var,
std::string compartment, std::string compartment2, std::string compartment, std::string compartment2,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + compartment2 + "::" + var; std::string nkey = compartment + "::" + compartment2 + "::" + var;
resolveMultiMatches(nkey, l, ke); resolveMultiMatches(nkey, l, ke);
@ -180,7 +180,7 @@ class Collection {
/* resolveRegularExpression */ /* resolveRegularExpression */
virtual void resolveRegularExpression(const std::string& var, virtual void resolveRegularExpression(const std::string& var,
std::string compartment, std::vector<const VariableValue *> *l, std::string compartment, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + var; std::string nkey = compartment + "::" + var;
resolveRegularExpression(nkey, l, ke); resolveRegularExpression(nkey, l, ke);
@ -189,7 +189,7 @@ class Collection {
virtual void resolveRegularExpression(const std::string& var, virtual void resolveRegularExpression(const std::string& var,
std::string compartment, std::string compartment2, std::string compartment, std::string compartment2,
std::vector<const VariableValue *> *l, variables::KeyExclusions &ke) { std::vector<std::shared_ptr<const VariableValue>> *l, variables::KeyExclusions &ke) {
std::string nkey = compartment + "::" + compartment2 + "::" + var; std::string nkey = compartment + "::" + compartment2 + "::" + var;
resolveRegularExpression(nkey, l, ke); resolveRegularExpression(nkey, l, ke);
} }

View File

@ -37,7 +37,7 @@ class VariableOrigin {
: m_length(0), : m_length(0),
m_offset(0) { } m_offset(0) { }
std::string toText() { std::string toText() const {
std::string offset = std::to_string(m_offset); std::string offset = std::to_string(m_offset);
std::string len = std::to_string(m_length); std::string len = std::to_string(m_length);
return "v" + offset + "," + len; return "v" + offset + "," + len;

View File

@ -37,7 +37,7 @@ namespace modsecurity {
class Collection; class Collection;
class VariableValue { class VariableValue {
public: public:
using Origins = std::list<std::unique_ptr<VariableOrigin>>; using Origins = std::vector<VariableOrigin>;
explicit VariableValue(const std::string *key, explicit VariableValue(const std::string *key,
const std::string *value = nullptr) const std::string *value = nullptr)
@ -63,10 +63,10 @@ class VariableValue {
m_value(o->m_value) m_value(o->m_value)
{ {
for (auto &i : o->m_orign) { for (auto &i : o->m_orign) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); VariableOrigin *origin(new VariableOrigin());
origin->m_offset = i->m_offset; origin->m_offset = i.m_offset;
origin->m_length = i->m_length; origin->m_length = i.m_length;
m_orign.push_back(std::move(origin)); m_orign.push_back(*origin);
} }
} }
@ -77,10 +77,10 @@ class VariableValue {
m_value(o.m_value) m_value(o.m_value)
{ {
for (auto &i : o.m_orign) { for (auto &i : o.m_orign) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); VariableOrigin *origin(new VariableOrigin());
origin->m_offset = i->m_offset; origin->m_offset = i.m_offset;
origin->m_length = i->m_length; origin->m_length = i.m_length;
m_orign.push_back(std::move(origin)); m_orign.push_back(*origin);
} }
} }
@ -109,7 +109,7 @@ class VariableValue {
} }
void addOrigin(std::unique_ptr<VariableOrigin> origin) { void addOrigin(VariableOrigin origin) {
m_orign.push_back(std::move(origin)); m_orign.push_back(std::move(origin));
} }

View File

@ -113,15 +113,12 @@ bool SetVar::execute(Transaction *t) const noexcept {
} }
try { try {
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
m_variable->evaluate(t, &l); m_variable->evaluate(t, &l);
if (l.size() == 0) { if (l.size() == 0) {
value = 0; value = 0;
} else { } else {
value = stoi(l[0]->getValue()); value = stoi(l[0]->getValue());
for (auto &i : l) {
delete i;
}
} }
} catch (...) { } catch (...) {
value = 0; value = 0;

View File

@ -36,59 +36,45 @@ AnchoredSetVariable::AnchoredSetVariable(Transaction *t,
} }
AnchoredSetVariable::~AnchoredSetVariable() {
unset();
}
void AnchoredSetVariable::unset() { void AnchoredSetVariable::unset() {
for (const auto& x : *this) {
VariableValue *var = x.second;
delete var;
}
clear(); clear();
} }
void AnchoredSetVariable::set(const std::string &key, void AnchoredSetVariable::set(const std::string &key,
const std::string &value, size_t offset, size_t len) { const std::string &value, size_t offset, size_t len) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); auto var = std::make_shared<VariableValue>(&m_name, &key, &value);
std::string *v = new std::string(value);
VariableValue *var = new VariableValue(&m_name, &key, v);
delete v;
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = len; origin.m_offset = offset;
origin.m_length = len;
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
emplace(key, var); emplace(key, std::move(var));
} }
void AnchoredSetVariable::set(const std::string &key, void AnchoredSetVariable::set(const std::string &key,
const std::string &value, size_t offset) { const std::string &value, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); auto var = std::make_shared<VariableValue>(&m_name, &key, &value);
std::string *v = new std::string(value);
VariableValue *var = new VariableValue(&m_name, &key, v);
delete v;
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = value.size(); origin.m_offset = offset;
origin.m_length = value.size();
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
emplace(key, var); emplace(key, std::move(var));
} }
void AnchoredSetVariable::set(const std::string &key, void AnchoredSetVariable::set(const std::string &key,
const bpstd::string_view &value, size_t offset) { const bpstd::string_view &value, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::string v(value.c_str());
std::string *v = new std::string(value.c_str()); auto var = std::make_shared<VariableValue>(&m_name, &key, &v);
VariableValue *var = new VariableValue(&m_name, &key, v);
delete v;
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = value.size(); origin.m_offset = offset;
origin.m_length = value.size();
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
emplace(key, var); emplace(key, var);
@ -97,13 +83,12 @@ void AnchoredSetVariable::set(const std::string &key,
void AnchoredSetVariable::set(const std::string &key, void AnchoredSetVariable::set(const std::string &key,
const char *value, size_t offset) { const char *value, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::string v(value);
std::string *v = new std::string(value); auto var = std::make_shared<VariableValue>(&m_name, &key, &v);
VariableValue *var = new VariableValue(&m_name, &key, v);
delete v;
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = strlen(value); origin.m_offset = offset;
origin.m_length = strlen(value);
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
emplace(key, var); emplace(key, var);
@ -111,19 +96,19 @@ void AnchoredSetVariable::set(const std::string &key,
void AnchoredSetVariable::resolve( void AnchoredSetVariable::resolve(
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
for (const auto& x : *this) { for (const auto& x : *this) {
l->insert(l->begin(), new VariableValue(x.second)); l->insert(l->begin(), x.second);
} }
} }
void AnchoredSetVariable::resolve( void AnchoredSetVariable::resolve(
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
for (const auto& x : *this) { for (const auto& x : *this) {
if (!ke.toOmit(x.first)) { if (!ke.toOmit(x.first)) {
l->insert(l->begin(), new VariableValue(x.second)); l->insert(l->begin(), x.second);
} else { } else {
ms_dbg_a(m_transaction, 7, "Excluding key: " + x.first ms_dbg_a(m_transaction, 7, "Excluding key: " + x.first
+ " from target value."); + " from target value.");
@ -133,10 +118,10 @@ void AnchoredSetVariable::resolve(
void AnchoredSetVariable::resolve(const std::string &key, void AnchoredSetVariable::resolve(const std::string &key,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
auto range = this->equal_range(key); auto range = this->equal_range(key);
for (auto it = range.first; it != range.second; ++it) { for (auto it = range.first; it != range.second; ++it) {
l->push_back(new VariableValue(it->second)); l->push_back(it->second);
} }
} }
@ -154,19 +139,19 @@ std::unique_ptr<std::string> AnchoredSetVariable::resolveFirst(
void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
for (const auto& x : *this) { for (const auto& x : *this) {
int ret = Utils::regex_search(x.first, *r); int ret = Utils::regex_search(x.first, *r);
if (ret <= 0) { if (ret <= 0) {
continue; continue;
} }
l->insert(l->begin(), new VariableValue(x.second)); l->insert(l->begin(), x.second);
} }
} }
void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r, void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
for (const auto& x : *this) { for (const auto& x : *this) {
int ret = Utils::regex_search(x.first, *r); int ret = Utils::regex_search(x.first, *r);
@ -174,7 +159,7 @@ void AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,
continue; continue;
} }
if (!ke.toOmit(x.first)) { if (!ke.toOmit(x.first)) {
l->insert(l->begin(), new VariableValue(x.second)); l->insert(l->begin(), x.second);
} else { } else {
ms_dbg_a(m_transaction, 7, "Excluding key: " + x.first ms_dbg_a(m_transaction, 7, "Excluding key: " + x.first
+ " from target value."); + " from target value.");

View File

@ -32,22 +32,11 @@ AnchoredVariable::AnchoredVariable(Transaction *t,
const std::string &name) const std::string &name)
: m_transaction(t), : m_transaction(t),
m_offset(0), m_offset(0),
m_name(""), m_name(name),
m_value(""), m_value(""),
m_var(NULL) { m_var(&name) {
m_name.append(name);
m_var = new VariableValue(&m_name);
} }
AnchoredVariable::~AnchoredVariable() {
if (m_var) {
delete (m_var);
m_var = NULL;
}
}
void AnchoredVariable::unset() { void AnchoredVariable::unset() {
m_value.clear(); m_value.clear();
} }
@ -55,92 +44,86 @@ void AnchoredVariable::unset() {
void AnchoredVariable::set(const std::string &a, size_t offset, void AnchoredVariable::set(const std::string &a, size_t offset,
size_t offsetLen) { size_t offsetLen) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
m_offset = offset; m_offset = offset;
m_value.assign(a.c_str(), a.size()); m_value.assign(a.c_str(), a.size());
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = offsetLen; origin.m_offset = offset;
m_var->addOrigin(std::move(origin)); origin.m_length = offsetLen;
m_var.addOrigin(std::move(origin));
} }
void AnchoredVariable::set(const std::string &a, size_t offset) { void AnchoredVariable::set(const std::string &a, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
m_offset = offset; m_offset = offset;
m_value.assign(a.c_str(), a.size()); m_value.assign(a.c_str(), a.size());
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = m_value.size(); origin.m_offset = offset;
m_var->addOrigin(std::move(origin)); origin.m_length = m_value.size();
m_var.addOrigin(std::move(origin));
} }
void AnchoredVariable::set(const char *a, size_t offset) { void AnchoredVariable::set(const char *a, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); VariableOrigin origin;
m_offset = offset; m_offset = offset;
m_value.assign(a, strlen(a)); m_value.assign(a, strlen(a));
origin->m_offset = offset; origin.m_offset = offset;
origin->m_length = m_value.size(); origin.m_length = m_value.size();
m_var->addOrigin(std::move(origin)); m_var.addOrigin(std::move(origin));
} }
void AnchoredVariable::set(const bpstd::string_view &a, size_t offset) { void AnchoredVariable::set(const bpstd::string_view &a, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); VariableOrigin origin;
m_offset = offset; m_offset = offset;
m_value.assign(a.c_str(), a.size()); m_value.assign(a.c_str(), a.size());
origin->m_offset = offset; origin.m_offset = offset;
origin->m_length = m_value.size(); origin.m_length = m_value.size();
m_var->addOrigin(std::move(origin)); m_var.addOrigin(std::move(origin));
} }
void AnchoredVariable::append(const std::string &a, size_t offset, void AnchoredVariable::append(const std::string &a, size_t offset,
bool spaceSeparator) { bool spaceSeparator) {
std::unique_ptr<VariableOrigin> origin(
new VariableOrigin());
if (spaceSeparator && !m_value.empty()) { if (spaceSeparator && !m_value.empty()) {
m_value.append(" " + a); m_value.append(" " + a);
} else { } else {
m_value.append(a); m_value.append(a);
} }
m_offset = offset; m_offset = offset;
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = a.size(); origin.m_offset = offset;
m_var->addOrigin(std::move(origin)); origin.m_length = a.size();
m_var.addOrigin(std::move(origin));
} }
void AnchoredVariable::append(const std::string &a, size_t offset, void AnchoredVariable::append(const std::string &a, size_t offset,
bool spaceSeparator, int size) { bool spaceSeparator, int size) {
std::unique_ptr<VariableOrigin> origin(
new VariableOrigin());
if (spaceSeparator && !m_value.empty()) { if (spaceSeparator && !m_value.empty()) {
m_value.append(" " + a); m_value.append(" " + a);
} else { } else {
m_value.append(a); m_value.append(a);
} }
m_offset = offset; m_offset = offset;
origin->m_offset = offset; VariableOrigin origin;
origin->m_length = size; origin.m_offset = offset;
m_var->addOrigin(std::move(origin)); origin.m_length = size;
m_var.addOrigin(std::move(origin));
} }
void AnchoredVariable::evaluate(std::vector<const VariableValue *> *l) { void AnchoredVariable::evaluate(std::vector<std::shared_ptr<const VariableValue>> *l) {
if (m_name.empty()) { if (m_name.empty()) {
return; return;
} }
m_var->setValue(m_value); m_var.setValue(m_value);
VariableValue *m_var2 = new VariableValue(m_var); l->push_back(std::make_shared<VariableValue>(m_var));
l->push_back(m_var2);
} }

View File

@ -86,17 +86,17 @@ void InMemoryPerProcess::del(const std::string& key) {
void InMemoryPerProcess::resolveSingleMatch(const std::string& var, void InMemoryPerProcess::resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
auto range = this->equal_range(var); auto range = this->equal_range(var);
for (auto it = range.first; it != range.second; ++it) { for (auto it = range.first; it != range.second; ++it) {
l->push_back(new VariableValue(&m_name, &it->first, &it->second)); l->push_back(std::make_shared<VariableValue>(&m_name, &it->first, &it->second));
} }
} }
void InMemoryPerProcess::resolveMultiMatches(const std::string& var, void InMemoryPerProcess::resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l, variables::KeyExclusions &ke) { std::vector<std::shared_ptr<const VariableValue>> *l, variables::KeyExclusions &ke) {
size_t keySize = var.size(); size_t keySize = var.size();
l->reserve(15); l->reserve(15);
@ -105,8 +105,7 @@ void InMemoryPerProcess::resolveMultiMatches(const std::string& var,
if (ke.toOmit(i.first)) { if (ke.toOmit(i.first)) {
continue; continue;
} }
l->insert(l->begin(), new VariableValue(&m_name, &i.first, l->insert(l->begin(), std::make_shared<VariableValue>(&m_name, &i.first, &i.second));
&i.second));
} }
} else { } else {
auto range = this->equal_range(var); auto range = this->equal_range(var);
@ -114,15 +113,14 @@ void InMemoryPerProcess::resolveMultiMatches(const std::string& var,
if (ke.toOmit(var)) { if (ke.toOmit(var)) {
continue; continue;
} }
l->insert(l->begin(), new VariableValue(&m_name, &var, l->insert(l->begin(), std::make_shared<VariableValue>(&m_name, &var, &it->second));
&it->second));
} }
} }
} }
void InMemoryPerProcess::resolveRegularExpression(const std::string& var, void InMemoryPerProcess::resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l, variables::KeyExclusions &ke) { std::vector<std::shared_ptr<const VariableValue>> *l, variables::KeyExclusions &ke) {
//if (var.find(":") == std::string::npos) { //if (var.find(":") == std::string::npos) {
// return; // return;
@ -155,7 +153,7 @@ void InMemoryPerProcess::resolveRegularExpression(const std::string& var,
if (ke.toOmit(x.first)) { if (ke.toOmit(x.first)) {
continue; continue;
} }
l->insert(l->begin(), new VariableValue(&m_name, &x.first, &x.second)); l->insert(l->begin(), std::make_shared<VariableValue>(&m_name, &x.first, &x.second));
} }
} }

View File

@ -87,12 +87,12 @@ class InMemoryPerProcess :
std::unique_ptr<std::string> resolveFirst(const std::string& var) override; std::unique_ptr<std::string> resolveFirst(const std::string& var) override;
void resolveSingleMatch(const std::string& var, void resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
void resolveMultiMatches(const std::string& var, void resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) override; variables::KeyExclusions &ke) override;
void resolveRegularExpression(const std::string& var, void resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) override; variables::KeyExclusions &ke) override;
private: private:

View File

@ -262,7 +262,7 @@ end_txn:
void LMDB::resolveSingleMatch(const std::string& var, void LMDB::resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
int rc; int rc;
MDB_txn *txn; MDB_txn *txn;
MDB_dbi dbi; MDB_dbi dbi;
@ -287,11 +287,10 @@ void LMDB::resolveSingleMatch(const std::string& var,
mdb_cursor_open(txn, dbi, &cursor); mdb_cursor_open(txn, dbi, &cursor);
while ((rc = mdb_cursor_get(cursor, &mdb_key, while ((rc = mdb_cursor_get(cursor, &mdb_key,
&mdb_value_ret, MDB_NEXT_DUP)) == 0) { &mdb_value_ret, MDB_NEXT_DUP)) == 0) {
std::string *a = new std::string( std::string a(
reinterpret_cast<char *>(mdb_value_ret.mv_data), reinterpret_cast<char *>(mdb_value_ret.mv_data),
mdb_value_ret.mv_size); mdb_value_ret.mv_size);
VariableValue *v = new VariableValue(&var, a); l->emplace_back(&var, &a);
l->push_back(v);
} }
mdb_cursor_close(cursor); mdb_cursor_close(cursor);
@ -466,7 +465,7 @@ end_txn:
void LMDB::resolveMultiMatches(const std::string& var, void LMDB::resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
MDB_val key, data; MDB_val key, data;
MDB_txn *txn = NULL; MDB_txn *txn = NULL;
@ -496,7 +495,7 @@ void LMDB::resolveMultiMatches(const std::string& var,
if (keySize == 0) { if (keySize == 0) {
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
l->insert(l->begin(), new VariableValue( l->insert(l->begin(), std::make_shared<VariableValue>(
&m_name, &m_name,
new std::string(reinterpret_cast<char *>(key.mv_data), new std::string(reinterpret_cast<char *>(key.mv_data),
key.mv_size), key.mv_size),
@ -507,7 +506,7 @@ void LMDB::resolveMultiMatches(const std::string& var,
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
char *a = reinterpret_cast<char *>(key.mv_data); char *a = reinterpret_cast<char *>(key.mv_data);
if (strncmp(var.c_str(), a, keySize) == 0) { if (strncmp(var.c_str(), a, keySize) == 0) {
l->insert(l->begin(), new VariableValue( l->insert(l->begin(), std::make_shared<VariableValue>(
&m_name, &m_name,
new std::string(reinterpret_cast<char *>(key.mv_data), new std::string(reinterpret_cast<char *>(key.mv_data),
key.mv_size), key.mv_size),
@ -528,7 +527,7 @@ end_txn:
void LMDB::resolveRegularExpression(const std::string& var, void LMDB::resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) { variables::KeyExclusions &ke) {
MDB_val key, data; MDB_val key, data;
MDB_txn *txn = NULL; MDB_txn *txn = NULL;

View File

@ -66,12 +66,12 @@ class LMDB :
std::unique_ptr<std::string> resolveFirst(const std::string& var) override; std::unique_ptr<std::string> resolveFirst(const std::string& var) override;
void resolveSingleMatch(const std::string& var, void resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
void resolveMultiMatches(const std::string& var, void resolveMultiMatches(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) override; variables::KeyExclusions &ke) override;
void resolveRegularExpression(const std::string& var, void resolveRegularExpression(const std::string& var,
std::vector<const VariableValue *> *l, std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke) override; variables::KeyExclusions &ke) override;
private: private:

View File

@ -286,7 +286,7 @@ int Lua::getvars(lua_State *L) {
const char *varname(NULL); const char *varname(NULL);
Transaction *t(NULL); Transaction *t(NULL);
void *z(NULL); void *z(NULL);
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
int idx = 1; int idx = 1;
/* Retrieve parameters. */ /* Retrieve parameters. */
@ -315,10 +315,6 @@ int Lua::getvars(lua_State *L) {
idx++; idx++;
} }
for (const VariableValue * i : l) {
delete i;
}
return 1; return 1;
} }

View File

@ -265,14 +265,16 @@ bool RuleWithOperator::evaluate(Transaction *trans) const {
getFinalVars(&vars, &exclusion, trans); getFinalVars(&vars, &exclusion, trans);
std::vector<std::shared_ptr<const VariableValue>> e;
for (auto &var : vars) { for (auto &var : vars) {
std::vector<const VariableValue *> e;
if (!var) { if (!var) {
continue; continue;
} }
e.clear();
var->evaluate(trans, &e); var->evaluate(trans, &e);
for (const VariableValue *v : e) { for (const auto &vv : e) {
TransformationsResults transformationsResults; TransformationsResults transformationsResults;
const VariableValue *v = vv.get();
const std::string &value = v->getValue(); const std::string &value = v->getValue();
const std::string &key = v->getKeyWithCollection(); const std::string &key = v->getKeyWithCollection();
@ -283,8 +285,6 @@ bool RuleWithOperator::evaluate(Transaction *trans) const {
return m.first == getId() && m.second == v->getKeyWithCollection(); return m.first == getId() && m.second == v->getKeyWithCollection();
}) != trans->m_ruleRemoveTargetById.end() }) != trans->m_ruleRemoveTargetById.end()
) { ) {
delete v;
v = NULL;
continue; continue;
} }
if (exclusion.contains(v) || if (exclusion.contains(v) ||
@ -294,8 +294,6 @@ bool RuleWithOperator::evaluate(Transaction *trans) const {
return containsTag(m.first, trans) && m.second == v->getKeyWithCollection(); return containsTag(m.first, trans) && m.second == v->getKeyWithCollection();
}) != trans->m_ruleRemoveTargetByTag.end() }) != trans->m_ruleRemoveTargetByTag.end()
) { ) {
delete v;
v = NULL;
continue; continue;
} }
@ -317,8 +315,8 @@ bool RuleWithOperator::evaluate(Transaction *trans) const {
trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans, trans->messageGetLast()->m_match = m_operator->resolveMatchMessage(trans,
key, value); key, value);
for (auto &i : v->getOrigin()) { for (const auto &i : v->getOrigin()) {
trans->messageGetLast()->m_reference.append(i->toText()); trans->messageGetLast()->m_reference.append(i.toText());
} }
auto iter2 = transformationsResults.begin(); auto iter2 = transformationsResults.begin();
@ -344,11 +342,7 @@ bool RuleWithOperator::evaluate(Transaction *trans) const {
iter++; iter++;
} }
delete v;
v = NULL;
} }
e.clear();
e.reserve(4);
} }
if (globalRet == false) { if (globalRet == false) {

View File

@ -54,14 +54,11 @@ std::string RunTimeString::evaluate(Transaction *transaction) {
if (element->m_string.size() > 0) { if (element->m_string.size() > 0) {
retString.append(element->m_string); retString.append(element->m_string);
} else if (element->m_variable != nullptr && transaction != nullptr) { } else if (element->m_variable != nullptr && transaction != nullptr) {
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
element->m_variable->evaluate(transaction, &l); element->m_variable->evaluate(transaction, &l);
if (!l.empty()) { if (!l.empty()) {
retString.append(l[0]->getValue()); retString.append(l[0]->getValue());
} }
for (auto &i : l) {
delete i;
}
} }
} }
return retString; return retString;

View File

@ -962,11 +962,10 @@ int Transaction::processRequestBody() {
* computationally intensive. * computationally intensive.
*/ */
std::string fullRequest; std::string fullRequest;
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
m_variableRequestHeaders.resolve(&l); m_variableRequestHeaders.resolve(&l);
for (auto &h : l) { for (const auto &h : l) {
fullRequest = fullRequest + h->getKey() + ": " + h->getValue() + "\n"; fullRequest = fullRequest + h->getKey() + ": " + h->getValue() + "\n";
delete h;
} }
fullRequest = fullRequest + "\n\n"; fullRequest = fullRequest + "\n\n";
@ -1492,7 +1491,7 @@ std::string Transaction::toOldAuditLogFormatIndex(const std::string &filename,
ss << utils::string::dash_if_empty(this->m_clientIpAddress->c_str()) << " "; ss << utils::string::dash_if_empty(this->m_clientIpAddress->c_str()) << " ";
/** TODO: Check variable */ /** TODO: Check variable */
variables::RemoteUser *r = new variables::RemoteUser("REMOTE_USER"); variables::RemoteUser *r = new variables::RemoteUser("REMOTE_USER");
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
r->evaluate(this, &l); r->evaluate(this, &l);
delete r; delete r;
@ -1555,7 +1554,7 @@ std::string Transaction::toOldAuditLogFormat(int parts,
audit_log << std::endl; audit_log << std::endl;
if (parts & audit_log::AuditLog::BAuditLogPart) { if (parts & audit_log::AuditLog::BAuditLogPart) {
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
audit_log << "--" << trailer << "-" << "B--" << std::endl; audit_log << "--" << trailer << "-" << "B--" << std::endl;
audit_log << utils::string::dash_if_empty( audit_log << utils::string::dash_if_empty(
m_variableRequestMethod.evaluate()); m_variableRequestMethod.evaluate());
@ -1563,11 +1562,10 @@ std::string Transaction::toOldAuditLogFormat(int parts,
audit_log << this->m_httpVersion.c_str() << std::endl; audit_log << this->m_httpVersion.c_str() << std::endl;
m_variableRequestHeaders.resolve(&l); m_variableRequestHeaders.resolve(&l);
for (auto &h : l) { for (const auto &h : l) {
size_t pos = strlen("REQUEST_HEADERS:"); size_t pos = strlen("REQUEST_HEADERS:");
audit_log << h->getKeyWithCollection().c_str() + pos << ": "; audit_log << h->getKeyWithCollection().c_str() + pos << ": ";
audit_log << h->getValue().c_str() << std::endl; audit_log << h->getValue().c_str() << std::endl;
delete h;
} }
audit_log << std::endl; audit_log << std::endl;
} }
@ -1595,16 +1593,15 @@ std::string Transaction::toOldAuditLogFormat(int parts,
audit_log << std::endl; audit_log << std::endl;
} }
if (parts & audit_log::AuditLog::FAuditLogPart) { if (parts & audit_log::AuditLog::FAuditLogPart) {
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
audit_log << "--" << trailer << "-" << "F--" << std::endl; audit_log << "--" << trailer << "-" << "F--" << std::endl;
audit_log << "HTTP/" << m_httpVersion.c_str() << " "; audit_log << "HTTP/" << m_httpVersion.c_str() << " ";
audit_log << this->m_httpCodeReturned << std::endl; audit_log << this->m_httpCodeReturned << std::endl;
m_variableResponseHeaders.resolve(&l); m_variableResponseHeaders.resolve(&l);
for (auto &h : l) { for (const auto &h : l) {
audit_log << h->getKey().c_str() << ": "; audit_log << h->getKey().c_str() << ": ";
audit_log << h->getValue().c_str() << std::endl; audit_log << h->getValue().c_str() << std::endl;
delete h;
} }
} }
audit_log << std::endl; audit_log << std::endl;
@ -1697,15 +1694,14 @@ std::string Transaction::toJSON(int parts) {
/* request headers */ /* request headers */
if (parts & audit_log::AuditLog::BAuditLogPart) { if (parts & audit_log::AuditLog::BAuditLogPart) {
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
yajl_gen_string(g, reinterpret_cast<const unsigned char*>("headers"), yajl_gen_string(g, reinterpret_cast<const unsigned char*>("headers"),
strlen("headers")); strlen("headers"));
yajl_gen_map_open(g); yajl_gen_map_open(g);
m_variableRequestHeaders.resolve(&l); m_variableRequestHeaders.resolve(&l);
for (auto &h : l) { for (const auto &h : l) {
LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str());
delete h;
} }
/* end: request headers */ /* end: request headers */
@ -1727,15 +1723,14 @@ std::string Transaction::toJSON(int parts) {
/* response headers */ /* response headers */
if (parts & audit_log::AuditLog::FAuditLogPart) { if (parts & audit_log::AuditLog::FAuditLogPart) {
std::vector<const VariableValue *> l; std::vector<std::shared_ptr<const VariableValue>> l;
yajl_gen_string(g, reinterpret_cast<const unsigned char*>("headers"), yajl_gen_string(g, reinterpret_cast<const unsigned char*>("headers"),
strlen("headers")); strlen("headers"));
yajl_gen_map_open(g); yajl_gen_map_open(g);
m_variableResponseHeaders.resolve(&l); m_variableResponseHeaders.resolve(&l);
for (auto &h : l) { for (const auto &h : l) {
LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str()); LOGFY_ADD(h->getKey().c_str(), h->getValue().c_str());
delete h;
} }
/* end: response headers */ /* end: response headers */

View File

@ -28,13 +28,12 @@ namespace modsecurity {
namespace variables { namespace variables {
void Duration::evaluate(Transaction *transaction, void Duration::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
double e = utils::cpu_seconds() - transaction->m_creationTimeStamp; double e = utils::cpu_seconds() - transaction->m_creationTimeStamp;
transaction->m_variableDuration.assign(std::to_string(e)); transaction->m_variableDuration.assign(std::to_string(e));
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableDuration));
&transaction->m_variableDuration));
} }

View File

@ -35,7 +35,7 @@ class Duration : public Variable {
m_retName("DURATION") { } m_retName("DURATION") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -33,7 +33,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void Env::evaluate(Transaction *transaction, void Env::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
for (char **current = environ; *current; current++) { for (char **current = environ; *current; current++) {
std::string env = std::string(*current); std::string env = std::string(*current);
size_t pos = env.find_first_of("="); size_t pos = env.find_first_of("=");
@ -51,8 +51,7 @@ void Env::evaluate(Transaction *transaction,
continue; continue;
} }
if (!m_keyExclusion.toOmit(x.first)) { if (!m_keyExclusion.toOmit(x.first)) {
l->push_back(new VariableValue(&m_collectionName, &x.first, l->emplace_back(std::make_shared<VariableValue>(&m_collectionName, &x.first, &x.second));
&x.second));
} }
} }
} }

View File

@ -34,7 +34,7 @@ class Env : public Variable {
: Variable(_name) { } : Variable(_name) { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
}; };
} // namespace variables } // namespace variables

View File

@ -40,7 +40,7 @@ class Global_DictElement : public Variable {
m_dictElement("GLOBAL:" + dictElement) { } m_dictElement("GLOBAL:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_global_collection->resolveMultiMatches( t->m_collections.m_global_collection->resolveMultiMatches(
m_name, t->m_collections.m_global_collection_key, m_name, t->m_collections.m_global_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -56,7 +56,7 @@ class Global_NoDictElement : public Variable {
: Variable("GLOBAL") { } : Variable("GLOBAL") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_global_collection->resolveMultiMatches("", t->m_collections.m_global_collection->resolveMultiMatches("",
t->m_collections.m_global_collection_key, t->m_collections.m_global_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -71,7 +71,7 @@ class Global_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_global_collection->resolveRegularExpression( t->m_collections.m_global_collection->resolveRegularExpression(
m_dictElement, m_dictElement,
t->m_collections.m_global_collection_key, t->m_collections.m_global_collection_key,
@ -92,7 +92,7 @@ class Global_DynamicElement : public VariableWithRunTimeString {
{ }; { };
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_global_collection->resolveMultiMatches( t->m_collections.m_global_collection->resolveMultiMatches(
string, string,

View File

@ -27,11 +27,10 @@ namespace modsecurity {
namespace variables { namespace variables {
void HighestSeverity::evaluate(Transaction *transaction, void HighestSeverity::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
transaction->m_variableHighestSeverityAction.assign( transaction->m_variableHighestSeverityAction.assign(
std::to_string(transaction->m_highestSeverityAction)); std::to_string(transaction->m_highestSeverityAction));
l->push_back(new VariableValue(m_fullName.get(), l->push_back(std::make_shared<VariableValue>(m_fullName.get(), &transaction->m_variableHighestSeverityAction));
&transaction->m_variableHighestSeverityAction));
} }

View File

@ -35,7 +35,7 @@ class HighestSeverity : public Variable {
{ } { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
}; };

View File

@ -40,7 +40,7 @@ class Ip_DictElement : public Variable {
m_dictElement("IP:" + dictElement) { } m_dictElement("IP:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_ip_collection->resolveMultiMatches( t->m_collections.m_ip_collection->resolveMultiMatches(
m_name, t->m_collections.m_ip_collection_key, m_name, t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -56,7 +56,7 @@ class Ip_NoDictElement : public Variable {
: Variable("IP") { } : Variable("IP") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_ip_collection->resolveMultiMatches("", t->m_collections.m_ip_collection->resolveMultiMatches("",
t->m_collections.m_ip_collection_key, t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -71,7 +71,7 @@ class Ip_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_ip_collection->resolveRegularExpression( t->m_collections.m_ip_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_ip_collection_key, m_dictElement, t->m_collections.m_ip_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -91,7 +91,7 @@ class Ip_DynamicElement : public VariableWithRunTimeString {
{ } { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_ip_collection->resolveMultiMatches( t->m_collections.m_ip_collection->resolveMultiMatches(
string, string,

View File

@ -25,9 +25,9 @@ namespace modsecurity {
namespace variables { namespace variables {
void ModsecBuild::evaluate(Transaction *transaction, void ModsecBuild::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
l->push_back(new VariableValue(&m_retName, &m_build)); l->push_back(std::make_shared<VariableValue>(&m_retName, &m_build));
} }

View File

@ -44,7 +44,7 @@ class ModsecBuild : public Variable {
} }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_build; std::string m_build;
std::string m_retName; std::string m_retName;

View File

@ -37,21 +37,19 @@ namespace variables {
void RemoteUser::evaluate(Transaction *transaction, void RemoteUser::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
size_t pos; size_t pos;
std::string base64; std::string base64;
VariableValue *var;
std::string header; std::string header;
std::vector<const VariableValue *> *l2 = \ std::vector<std::shared_ptr<const VariableValue>> l2;
new std::vector<const VariableValue *>(); transaction->m_variableRequestHeaders.resolve("authorization", &l2);
transaction->m_variableRequestHeaders.resolve("authorization", l2);
if (l2->size() < 1) { if (l2.size() < 1) {
goto clear; return;
} }
header = std::string(l2->at(0)->getValue()); header = std::string(l2.at(0)->getValue());
if (header.compare(0, 6, "Basic ") == 0) { if (header.compare(0, 6, "Basic ") == 0) {
base64 = std::string(header, 6, header.length()); base64 = std::string(header, 6, header.length());
@ -61,27 +59,16 @@ void RemoteUser::evaluate(Transaction *transaction,
pos = base64.find(":"); pos = base64.find(":");
if (pos == std::string::npos) { if (pos == std::string::npos) {
goto clear; return;
} }
transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos)); transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos));
var = new VariableValue(&l2->at(0)->getKeyWithCollection(), auto var = std::make_shared<VariableValue>(&l2[0]->getKeyWithCollection(), &transaction->m_variableRemoteUser);
&transaction->m_variableRemoteUser);
for (auto &i : l2->at(0)->getOrigin()) { for (auto &i : l2[0]->getOrigin()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); var->addOrigin(i);
origin->m_offset = i->m_offset;
origin->m_length = i->m_length;
var->addOrigin(std::move(origin));
} }
l->push_back(var); l->push_back(std::move(var));
clear:
for (auto &a : *l2) {
delete a;
}
l2->clear();
delete l2;
} }

View File

@ -37,7 +37,7 @@ class RemoteUser : public Variable {
m_retName("REMOTE_USER") { } m_retName("REMOTE_USER") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -40,7 +40,7 @@ class Resource_DictElement : public Variable {
m_dictElement("RESOURCE:" + dictElement) { } m_dictElement("RESOURCE:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_resource_collection->resolveMultiMatches( t->m_collections.m_resource_collection->resolveMultiMatches(
m_name, t->m_collections.m_resource_collection_key, m_name, t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -56,7 +56,7 @@ class Resource_NoDictElement : public Variable {
: Variable("RESOURCE") { } : Variable("RESOURCE") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_resource_collection->resolveMultiMatches(m_name, t->m_collections.m_resource_collection->resolveMultiMatches(m_name,
t->m_collections.m_resource_collection_key, t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -71,7 +71,7 @@ class Resource_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_resource_collection->resolveRegularExpression( t->m_collections.m_resource_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_resource_collection_key, m_dictElement, t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -91,7 +91,7 @@ class Resource_DynamicElement : public VariableWithRunTimeString {
{ } { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_resource_collection->resolveMultiMatches( t->m_collections.m_resource_collection->resolveMultiMatches(
string, string,

View File

@ -56,97 +56,83 @@ class Rule_DictElement : public RuleVariable, public VariableDictElement {
static void id(Transaction *t, static void id(Transaction *t,
const RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::string a = std::to_string(rule->getId());
std::string *a = new std::string(std::to_string(rule->getId())); auto var = std::make_shared<VariableValue>(&m_rule, &m_rule_id, &a);
VariableValue *var = new VariableValue(&m_rule, &m_rule_id, VariableOrigin origin;
a origin.m_offset = 0;
); origin.m_length = 0;
delete a;
origin->m_offset = 0;
origin->m_length = 0;
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
l->push_back(var); l->push_back(std::move(var));
} }
static void rev(Transaction *t, static void rev(Transaction *t,
const RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
if (rule->hasRevisionAction()) { if (rule->hasRevisionAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::string a(rule->getRevision());
std::string *a = new std::string(rule->getRevision()); auto var = std::make_shared<VariableValue>(&m_rule, &m_rule_rev, &a);
VariableValue *var = new VariableValue(&m_rule, &m_rule_rev, VariableOrigin origin;
a origin.m_offset = 0;
); origin.m_length = 0;
delete a;
origin->m_offset = 0;
origin->m_length = 0;
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
l->push_back(var); l->push_back(var);
l->push_back(std::move(var));
} }
} }
static void severity(Transaction *t, static void severity(Transaction *t,
const RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
if (rule->hasSeverityAction()) { if (rule->hasSeverityAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::string a(std::to_string(rule->getSeverity()));
std::string *a = new std::string(std::to_string(rule->getSeverity())); auto var = std::make_shared<VariableValue>(&m_rule, &m_rule_severity, &a);
VariableValue *var = new VariableValue(&m_rule, &m_rule_severity, VariableOrigin origin;
a origin.m_offset = 0;
); origin.m_length = 0;
delete a;
origin->m_offset = 0;
origin->m_length = 0;
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
l->push_back(var); l->push_back(std::move(var));
} }
} }
static void logData(Transaction *t, static void logData(Transaction *t,
const RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
if (rule->hasLogDataAction()) { if (rule->hasLogDataAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::string a(rule->getLogData(t));
std::string *a = new std::string(rule->getLogData(t)); auto var = std::make_shared<VariableValue>(&m_rule, &m_rule_logdata, &a);
VariableValue *var = new VariableValue(&m_rule, &m_rule_logdata, VariableOrigin origin;
a origin.m_offset = 0;
); origin.m_length = 0;
delete a;
origin->m_offset = 0;
origin->m_length = 0;
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
l->push_back(var); l->push_back(std::move(var));
} }
} }
static void msg(Transaction *t, static void msg(Transaction *t,
const RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
if (rule->hasMessageAction()) { if (rule->hasMessageAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::string a(rule->getMessage(t));
std::string *a = new std::string(rule->getMessage(t)); auto var = std::make_shared<VariableValue>(&m_rule, &m_rule_msg, &a);
VariableValue *var = new VariableValue(&m_rule, &m_rule_msg, VariableOrigin origin;
a origin.m_offset = 0;
); origin.m_length = 0;
delete a;
origin->m_offset = 0;
origin->m_length = 0;
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
l->push_back(var); l->push_back(std::move(var));
} }
} }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
if (m_dictElement == "id") { if (m_dictElement == "id") {
id(t, getRule(), l); id(t, getRule(), l);
@ -194,7 +180,7 @@ class Rule_DictElementRegexp : public RuleVariable, public VariableRegex {
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
if (Utils::regex_search("id", m_r) > 0) { if (Utils::regex_search("id", m_r) > 0) {
Rule_DictElement::id(t, getRule(), l); Rule_DictElement::id(t, getRule(), l);
@ -239,7 +225,7 @@ class Rule_NoDictElement : public RuleVariable, public Variable {
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
Rule_DictElement::id(t, getRule(), l); Rule_DictElement::id(t, getRule(), l);
Rule_DictElement::rev(t, getRule(), l); Rule_DictElement::rev(t, getRule(), l);
Rule_DictElement::severity(t, getRule(), l); Rule_DictElement::severity(t, getRule(), l);

View File

@ -39,7 +39,7 @@ class Session_DictElement : public Variable {
m_dictElement("SESSION:" + dictElement) { } m_dictElement("SESSION:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_session_collection->resolveMultiMatches( t->m_collections.m_session_collection->resolveMultiMatches(
m_name, t->m_collections.m_session_collection_key, m_name, t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -55,7 +55,7 @@ class Session_NoDictElement : public Variable {
: Variable("SESSION") { } : Variable("SESSION") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_session_collection->resolveMultiMatches("", t->m_collections.m_session_collection->resolveMultiMatches("",
t->m_collections.m_session_collection_key, t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -70,7 +70,7 @@ class Session_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_session_collection->resolveRegularExpression( t->m_collections.m_session_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_session_collection_key, m_dictElement, t->m_collections.m_session_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -90,7 +90,7 @@ class Session_DynamicElement : public VariableWithRunTimeString {
{ } { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_session_collection->resolveMultiMatches( t->m_collections.m_session_collection->resolveMultiMatches(
string, string,

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void Time::evaluate(Transaction *transaction, void Time::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
@ -47,8 +47,7 @@ void Time::evaluate(Transaction *transaction,
strftime(tstr, 200, "%H:%M:%S", &timeinfo); strftime(tstr, 200, "%H:%M:%S", &timeinfo);
transaction->m_variableTime.assign(tstr); transaction->m_variableTime.assign(tstr);
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTime));
&transaction->m_variableTime));
} }

View File

@ -36,7 +36,7 @@ class Time : public Variable {
m_retName("TIME") { } m_retName("TIME") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeDay::evaluate(Transaction *transaction, void TimeDay::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
time_t timer; time_t timer;
@ -47,8 +47,7 @@ void TimeDay::evaluate(Transaction *transaction,
transaction->m_variableTimeDay.assign(tstr); transaction->m_variableTimeDay.assign(tstr);
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeDay));
&transaction->m_variableTimeDay));
} }

View File

@ -35,7 +35,7 @@ class TimeDay : public Variable {
m_retName("TIME_DAY") { } m_retName("TIME_DAY") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,11 +34,10 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeEpoch::evaluate(Transaction *transaction, void TimeEpoch::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
transaction->m_variableTimeEpoch.assign( transaction->m_variableTimeEpoch.assign(
std::to_string(std::time(nullptr))); std::to_string(std::time(nullptr)));
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeEpoch));
&transaction->m_variableTimeEpoch));
} }

View File

@ -35,7 +35,7 @@ class TimeEpoch : public Variable {
m_retName("TIME_EPOCH") { } m_retName("TIME_EPOCH") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeHour::evaluate(Transaction *transaction, void TimeHour::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
time_t timer; time_t timer;
@ -47,8 +47,7 @@ void TimeHour::evaluate(Transaction *transaction,
transaction->m_variableTimeHour.assign(tstr); transaction->m_variableTimeHour.assign(tstr);
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeHour));
&transaction->m_variableTimeHour));
} }

View File

@ -35,7 +35,7 @@ class TimeHour : public Variable {
m_retName("TIME_HOUR") { } m_retName("TIME_HOUR") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeMin::evaluate(Transaction *transaction, void TimeMin::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
time_t timer; time_t timer;
@ -47,8 +47,7 @@ void TimeMin::evaluate(Transaction *transaction,
transaction->m_variableTimeMin.assign(tstr); transaction->m_variableTimeMin.assign(tstr);
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeMin));
&transaction->m_variableTimeMin));
} }

View File

@ -35,7 +35,7 @@ class TimeMin : public Variable {
m_retName("TIME_MIN") { } m_retName("TIME_MIN") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeMon::evaluate(Transaction *transaction, void TimeMon::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
time_t timer; time_t timer;
@ -49,8 +49,7 @@ void TimeMon::evaluate(Transaction *transaction,
transaction->m_variableTimeMin.assign(std::to_string(a)); transaction->m_variableTimeMin.assign(std::to_string(a));
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeMin));
&transaction->m_variableTimeMin));
} }

View File

@ -35,7 +35,7 @@ class TimeMon : public Variable {
m_retName("TIME_MON") { } m_retName("TIME_MON") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeSec::evaluate(Transaction *transaction, void TimeSec::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
time_t timer; time_t timer;
@ -47,8 +47,7 @@ void TimeSec::evaluate(Transaction *transaction,
transaction->m_variableTimeSec.assign(tstr); transaction->m_variableTimeSec.assign(tstr);
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeSec));
&transaction->m_variableTimeSec));
} }

View File

@ -35,7 +35,7 @@ class TimeSec : public Variable {
m_retName("TIME_SEC") { } m_retName("TIME_SEC") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeWDay::evaluate(Transaction *transaction, void TimeWDay::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
time_t timer; time_t timer;
@ -47,8 +47,7 @@ void TimeWDay::evaluate(Transaction *transaction,
transaction->m_variableTimeWDay.assign(tstr); transaction->m_variableTimeWDay.assign(tstr);
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeWDay));
&transaction->m_variableTimeWDay));
} }

View File

@ -35,7 +35,7 @@ class TimeWDay : public Variable {
m_retName("TIME_WDAY") { } m_retName("TIME_WDAY") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,7 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeYear::evaluate(Transaction *transaction, void TimeYear::evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;
time_t timer; time_t timer;
@ -47,8 +47,7 @@ void TimeYear::evaluate(Transaction *transaction,
transaction->m_variableTimeYear.assign(tstr); transaction->m_variableTimeYear.assign(tstr);
l->push_back(new VariableValue(&m_retName, l->push_back(std::make_shared<VariableValue>(&m_retName, &transaction->m_variableTimeYear));
&transaction->m_variableTimeYear));
} }

View File

@ -35,7 +35,7 @@ class TimeYear : public Variable {
m_retName("TIME_YEAR") { } m_retName("TIME_YEAR") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -40,7 +40,7 @@ class Tx_DictElement : public Variable {
m_dictElement("TX:" + dictElement) { } m_dictElement("TX:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_tx_collection->resolveMultiMatches( t->m_collections.m_tx_collection->resolveMultiMatches(
m_name, l, m_keyExclusion); m_name, l, m_keyExclusion);
} }
@ -55,7 +55,7 @@ class Tx_NoDictElement : public Variable {
: Variable("TX") { } : Variable("TX") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_tx_collection->resolveMultiMatches("", l, t->m_collections.m_tx_collection->resolveMultiMatches("", l,
m_keyExclusion); m_keyExclusion);
} }
@ -69,7 +69,7 @@ class Tx_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_tx_collection->resolveRegularExpression( t->m_collections.m_tx_collection->resolveRegularExpression(
m_dictElement, l, m_keyExclusion); m_dictElement, l, m_keyExclusion);
} }
@ -88,7 +88,7 @@ class Tx_DynamicElement : public VariableWithRunTimeString {
{ } { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_tx_collection->resolveMultiMatches(string, l, t->m_collections.m_tx_collection->resolveMultiMatches(string, l,
m_keyExclusion); m_keyExclusion);

View File

@ -40,7 +40,7 @@ class User_DictElement : public Variable {
m_dictElement("USER:" + dictElement) { } m_dictElement("USER:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_user_collection->resolveMultiMatches( t->m_collections.m_user_collection->resolveMultiMatches(
m_name, t->m_collections.m_user_collection_key, m_name, t->m_collections.m_user_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -56,7 +56,7 @@ class User_NoDictElement : public Variable {
: Variable("USER") { } : Variable("USER") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_user_collection->resolveMultiMatches(m_name, t->m_collections.m_user_collection->resolveMultiMatches(m_name,
t->m_collections.m_user_collection_key, t->m_collections.m_user_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -71,7 +71,7 @@ class User_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
t->m_collections.m_user_collection->resolveRegularExpression( t->m_collections.m_user_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_user_collection_key, m_dictElement, t->m_collections.m_user_collection_key,
t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion); t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);
@ -91,7 +91,7 @@ class User_DynamicElement : public VariableWithRunTimeString {
{ } { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_user_collection->resolveMultiMatches( t->m_collections.m_user_collection->resolveMultiMatches(
string, string,

View File

@ -48,7 +48,7 @@ class n ## _DictElementRegexp : public VariableRegex { \
: VariableRegex(#N, regex) { } \ : VariableRegex(#N, regex) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
std::vector<const VariableValue *> *l) override { \ std::vector<std::shared_ptr<const VariableValue>> *l) override { \
transaction-> e .resolveRegularExpression(&m_r, l, \ transaction-> e .resolveRegularExpression(&m_r, l, \
m_keyExclusion); \ m_keyExclusion); \
} \ } \
@ -62,7 +62,7 @@ class n ## _DictElement : public VariableDictElement { \
: VariableDictElement(#N, dictElement) { } \ : VariableDictElement(#N, dictElement) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
std::vector<const VariableValue *> *l) override { \ std::vector<std::shared_ptr<const VariableValue>> *l) override { \
transaction-> e .resolve(m_dictElement, l); \ transaction-> e .resolve(m_dictElement, l); \
} \ } \
}; };
@ -75,7 +75,7 @@ class n ## _NoDictElement : public Variable { \
: Variable(#N) { } \ : Variable(#N) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
std::vector<const VariableValue *> *l) override { \ std::vector<std::shared_ptr<const VariableValue>> *l) override { \
transaction-> e .resolve(l, m_keyExclusion); \ transaction-> e .resolve(l, m_keyExclusion); \
} \ } \
}; };
@ -88,7 +88,7 @@ class n : public Variable { \
: Variable(#N) { } \ : Variable(#N) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
std::vector<const VariableValue *> *l) override { \ std::vector<std::shared_ptr<const VariableValue>> *l) override { \
transaction-> e .evaluate(l); \ transaction-> e .evaluate(l); \
} \ } \
}; };
@ -186,7 +186,7 @@ class VariableMonkeyResolution {
static void stringMatchResolveMulti(Transaction *t, static void stringMatchResolveMulti(Transaction *t,
const std::string &variable, const std::string &variable,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
size_t collection = variable.find("."); size_t collection = variable.find(".");
if (collection == std::string::npos) { if (collection == std::string::npos) {
collection = variable.find(":"); collection = variable.find(":");
@ -567,7 +567,7 @@ class Variable : public VariableMonkeyResolution {
virtual void evaluate(Transaction *t, virtual void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) = 0; std::vector<std::shared_ptr<const VariableValue>> *l) = 0;
bool inline belongsToCollection(Variable *var) { bool inline belongsToCollection(Variable *var) {
@ -675,7 +675,7 @@ class VariableModificatorExclusion : public Variable {
m_base(std::move(var)) { } m_base(std::move(var)) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
m_base->evaluate(t, l); m_base->evaluate(t, l);
} }
@ -692,25 +692,14 @@ class VariableModificatorCount : public Variable {
} }
void evaluate(Transaction *t, void evaluate(Transaction *t,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
std::vector<const VariableValue *> reslIn;
VariableValue *val = NULL;
int count = 0;
std::vector<std::shared_ptr<const VariableValue>> reslIn;
m_base->evaluate(t, &reslIn); m_base->evaluate(t, &reslIn);
auto count = reslIn.size();
for (const VariableValue *a : reslIn) { std::string res(std::to_string(count));
count++; l->push_back(std::make_shared<VariableValue>(m_fullName.get(), &res));
delete a;
a = NULL;
}
reslIn.clear();
std::string *res = new std::string(std::to_string(count));
val = new VariableValue(m_fullName.get(), res);
delete res;
l->push_back(val);
return; return;
} }

View File

@ -36,9 +36,10 @@ class WebAppId : public Variable {
: Variable("WEBAPPID") { } : Variable("WEBAPPID") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
const std::string name("WEBAPPID");
const std::string rname = transaction->m_rules->m_secWebAppId.m_value; const std::string rname = transaction->m_rules->m_secWebAppId.m_value;
l->push_back(new VariableValue(&m_name, &rname)); l->push_back(std::make_shared<VariableValue>(&m_name, &rname));
} }
}; };

View File

@ -50,11 +50,11 @@ namespace variables {
#ifndef WITH_LIBXML2 #ifndef WITH_LIBXML2
void XML_WithNSPath::evaluate(Transaction *t, void XML_WithNSPath::evaluate(Transaction *t,
std::vector<const VariableValue *> *l) { } std::vector<std::shared_ptr<const VariableValue>> *l) { }
#else #else
void XML_WithNSPath::evaluate(Transaction *t, void XML_WithNSPath::evaluate(Transaction *t,
std::vector<const VariableValue *> *l) { std::vector<std::shared_ptr<const VariableValue>> *l) {
xmlXPathContextPtr xpathCtx; xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj; xmlXPathObjectPtr xpathObj;
xmlNodeSetPtr nodes; xmlNodeSetPtr nodes;
@ -123,13 +123,10 @@ void XML_WithNSPath::evaluate(Transaction *t,
content = reinterpret_cast<char *>( content = reinterpret_cast<char *>(
xmlNodeGetContent(nodes->nodeTab[i])); xmlNodeGetContent(nodes->nodeTab[i]));
if (content != NULL) { if (content != NULL) {
std::string *a = new std::string(content); std::string a(content);
VariableValue *var = new VariableValue(m_fullName.get(),
a);
if (!m_keyExclusion.toOmit(*m_fullName)) { if (!m_keyExclusion.toOmit(*m_fullName)) {
l->push_back(var); l->push_back(std::make_shared<VariableValue>(m_fullName.get(), &a));
} }
delete a;
xmlFree(content); xmlFree(content);
} }
} }

View File

@ -40,7 +40,7 @@ class XML_WithoutNSPath : public RuleVariable, public Variable {
: RuleVariable(), : RuleVariable(),
Variable("XML"), Variable("XML"),
m_plain("[XML document tree]"), m_plain("[XML document tree]"),
m_var(&m_name, &m_plain) m_var(std::make_shared<VariableValue>(&m_name, &m_plain))
{ }; { };
XML_WithoutNSPath(const XML_WithoutNSPath &r) XML_WithoutNSPath(const XML_WithoutNSPath &r)
@ -51,8 +51,8 @@ class XML_WithoutNSPath : public RuleVariable, public Variable {
{ }; { };
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override { std::vector<std::shared_ptr<const VariableValue>> *l) override {
l->push_back(new VariableValue(&m_var)); l->push_back(m_var);
} }
virtual variables::Variable *clone() override { virtual variables::Variable *clone() override {
@ -60,7 +60,7 @@ class XML_WithoutNSPath : public RuleVariable, public Variable {
}; };
std::string m_plain; std::string m_plain;
VariableValue m_var; std::shared_ptr<const VariableValue> m_var;
}; };
class XML_WithNSPath : public RuleVariable, public VariableDictElement { class XML_WithNSPath : public RuleVariable, public VariableDictElement {
@ -76,7 +76,7 @@ class XML_WithNSPath : public RuleVariable, public VariableDictElement {
{ }; { };
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
std::vector<const VariableValue *> *l) override; std::vector<std::shared_ptr<const VariableValue>> *l) override;
virtual Variable *clone() override { virtual Variable *clone() override {
return new XML_WithNSPath(*this); return new XML_WithNSPath(*this);