Skip to content

Improve performance of VariableOrigin instances #3164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions headers/modsecurity/anchored_set_variable_translation_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ class AnchoredSetVariableTranslationProxy {
VariableValue *newVariableValue = new VariableValue(name, &l->at(i)->getKey(), &l->at(i)->getKey());
const VariableValue *oldVariableValue = l->at(i);
l->at(i) = newVariableValue;
newVariableValue->reserveOrigin(oldVariableValue->getOrigin().size());
for (const auto &oldOrigin : oldVariableValue->getOrigin()) {
std::unique_ptr<VariableOrigin> newOrigin(new VariableOrigin);
newOrigin->m_length = oldVariableValue->getKey().size();
newOrigin->m_offset = oldOrigin->m_offset - oldVariableValue->getKey().size() - 1;
newVariableValue->addOrigin(std::move(newOrigin));
newVariableValue->addOrigin(
oldVariableValue->getKey().size(),
oldOrigin.m_offset - oldVariableValue->getKey().size() - 1
);
}
delete oldVariableValue;
}
Expand Down
16 changes: 2 additions & 14 deletions headers/modsecurity/anchored_variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,11 @@ class AnchoredVariable {
AnchoredVariable(const AnchoredVariable &a) = delete;
AnchoredVariable &operator= (const AnchoredVariable &a) = delete;

/*
: m_transaction(a.m_transaction),
m_offset(a.m_offset),
m_name(a.m_name),
m_value(a.m_value),
m_var(a.m_var) { }
*/

~AnchoredVariable();
~AnchoredVariable() = default;

void unset();
void set(const std::string &a, size_t offset);
void set(const std::string &a, size_t offset, size_t offsetLen);
void append(const std::string &a, size_t offset,
bool spaceSeparator = false);
void append(const std::string &a, size_t offset,
bool spaceSeparator, int size);

void evaluate(std::vector<const VariableValue *> *l);
std::string * evaluate();
Expand All @@ -75,7 +63,7 @@ class AnchoredVariable {
std::string m_value;

private:
VariableValue *m_var;
VariableValue m_var;
};

} // namespace modsecurity
Expand Down
12 changes: 8 additions & 4 deletions headers/modsecurity/variable_origin.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#ifdef __cplusplus
#include <string>
#include <memory>
#endif

#ifndef HEADERS_MODSECURITY_VARIABLE_ORIGIN_H_
Expand All @@ -36,14 +37,17 @@ class VariableOrigin {
VariableOrigin()
: m_length(0),
m_offset(0) { }
VariableOrigin(size_t length, size_t offset)
: m_length(length),
m_offset(offset) { }

std::string toText() {
std::string offset = std::to_string(m_offset);
std::string len = std::to_string(m_length);
std::string toText() const {
const auto offset = std::to_string(m_offset);
const auto len = std::to_string(m_length);
return "v" + offset + "," + len;
}

int m_length;
size_t m_length;
size_t m_offset;
};

Expand Down
26 changes: 18 additions & 8 deletions headers/modsecurity/variable_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <string>
#include <iostream>
#include <memory>
#include <list>
#include <vector>
#include <utility>
#endif

Expand All @@ -37,7 +37,7 @@ namespace modsecurity {
class Collection;
class VariableValue {
public:
using Origins = std::list<std::unique_ptr<VariableOrigin>>;
using Origins = std::vector<VariableOrigin>;

explicit VariableValue(const std::string *key,
const std::string *value = nullptr)
Expand All @@ -62,11 +62,9 @@ class VariableValue {
m_keyWithCollection(o->m_keyWithCollection),
m_value(o->m_value)
{
reserveOrigin(o->m_orign.size());
for (const auto &i : o->m_orign) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
origin->m_offset = i->m_offset;
origin->m_length = i->m_length;
m_orign.push_back(std::move(origin));
addOrigin(i);
}
}

Expand Down Expand Up @@ -98,15 +96,27 @@ class VariableValue {
}


void addOrigin(std::unique_ptr<VariableOrigin> origin) {
m_orign.push_back(std::move(origin));
void addOrigin(const VariableOrigin &origin) {
m_orign.emplace_back(origin);
}


template<typename... Args>
void addOrigin(Args&&... args) {
m_orign.emplace_back(args...);
}


const Origins& getOrigin() const {
return m_orign;
}


void reserveOrigin(Origins::size_type additionalSize) {
m_orign.reserve(m_orign.size() + additionalSize);
}


private:
Origins m_orign;
std::string m_collection;
Expand Down
14 changes: 2 additions & 12 deletions src/anchored_set_variable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,26 +52,16 @@ void AnchoredSetVariable::unset() {

void AnchoredSetVariable::set(const std::string &key,
const std::string &value, size_t offset, size_t len) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
VariableValue *var = new VariableValue(&m_name, &key, &value);

origin->m_offset = offset;
origin->m_length = len;

var->addOrigin(std::move(origin));
var->addOrigin(len, offset);
emplace(key, var);
}


void AnchoredSetVariable::set(const std::string &key,
const std::string &value, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
VariableValue *var = new VariableValue(&m_name, &key, &value);

origin->m_offset = offset;
origin->m_length = value.size();

var->addOrigin(std::move(origin));
var->addOrigin(value.size(), offset);
emplace(key, var);
}

Expand Down
69 changes: 7 additions & 62 deletions src/anchored_variable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,9 @@ AnchoredVariable::AnchoredVariable(Transaction *t,
const std::string &name)
: m_transaction(t),
m_offset(0),
m_name(""),
m_name(name),
m_value(""),
m_var(NULL) {
m_name.append(name);
m_var = new VariableValue(&m_name);
}


AnchoredVariable::~AnchoredVariable() {
if (m_var) {
delete (m_var);
m_var = NULL;
}
m_var(&name) {
}


Expand All @@ -54,58 +44,16 @@ void AnchoredVariable::unset() {

void AnchoredVariable::set(const std::string &a, size_t offset,
size_t offsetLen) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());

m_offset = offset;
m_value.assign(a.c_str(), a.size());
origin->m_offset = offset;
origin->m_length = offsetLen;
m_var->addOrigin(std::move(origin));
m_var.addOrigin(offsetLen, offset);
}


void AnchoredVariable::set(const std::string &a, size_t offset) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());

m_offset = offset;
m_value.assign(a.c_str(), a.size());
origin->m_offset = offset;
origin->m_length = m_value.size();
m_var->addOrigin(std::move(origin));
}


void AnchoredVariable::append(const std::string &a, size_t offset,
bool spaceSeparator) {
std::unique_ptr<VariableOrigin> origin(
new VariableOrigin());

if (spaceSeparator && !m_value.empty()) {
m_value.append(" " + a);
} else {
m_value.append(a);
}
m_offset = offset;
origin->m_offset = offset;
origin->m_length = a.size();
m_var->addOrigin(std::move(origin));
}


void AnchoredVariable::append(const std::string &a, size_t offset,
bool spaceSeparator, int size) {
std::unique_ptr<VariableOrigin> origin(
new VariableOrigin());

if (spaceSeparator && !m_value.empty()) {
m_value.append(" " + a);
} else {
m_value.append(a);
}
m_offset = offset;
origin->m_offset = offset;
origin->m_length = size;
m_var->addOrigin(std::move(origin));
m_var.addOrigin(m_value.size(), offset);
}


Expand All @@ -114,9 +62,8 @@ void AnchoredVariable::evaluate(std::vector<const VariableValue *> *l) {
return;
}

m_var->setValue(m_value);
VariableValue *m_var2 = new VariableValue(m_var);
l->push_back(m_var2);
m_var.setValue(m_value);
l->push_back(new VariableValue(&m_var));
}


Expand All @@ -129,9 +76,7 @@ std::unique_ptr<std::string> AnchoredVariable::resolveFirst() {
if (m_value.empty()) {
return nullptr;
}
std::unique_ptr<std::string> a(new std::string());
a->append(m_value);
return a;
return std::make_unique<std::string>(m_value);
}


Expand Down
4 changes: 2 additions & 2 deletions src/rule_with_operator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,8 @@ bool RuleWithOperator::evaluate(Transaction *trans,
if (ret == true) {
ruleMessage->m_match = m_operator->resolveMatchMessage(trans,
key, value);
for (auto &i : v->getOrigin()) {
ruleMessage->m_reference.append(i->toText());
for (const auto &i : v->getOrigin()) {
ruleMessage->m_reference.append(i.toText());
}

ruleMessage->m_reference.append(*valueTemp.second);
Expand Down
59 changes: 25 additions & 34 deletions src/variables/remote_user.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,50 +39,41 @@ namespace variables {
void RemoteUser::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) {
size_t pos;
std::string base64;
VariableValue *var;
std::string header;
std::vector<const VariableValue *> l2;

std::vector<const VariableValue *> *l2 = \
new std::vector<const VariableValue *>();
transaction->m_variableRequestHeaders.resolve("authorization", l2);
transaction->m_variableRequestHeaders.resolve("authorization", &l2);

if (l2->size() < 1) {
goto clear;
}
if (!l2.empty()) {
const auto *v = l2[0];

header = std::string(l2->at(0)->getValue());
const auto &header = v->getValue();

if (header.compare(0, 6, "Basic ") == 0) {
base64 = std::string(header, 6, header.length());
}
std::string base64;

base64 = Utils::Base64::decode(base64);
if (header.compare(0, 6, "Basic ") == 0) {
base64 = std::string(header, 6, header.length());
}

pos = base64.find(":");
if (pos == std::string::npos) {
goto clear;
}
transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos));
base64 = Utils::Base64::decode(base64);

var = new VariableValue(&l2->at(0)->getKeyWithCollection(),
&transaction->m_variableRemoteUser);
const auto pos = base64.find(":");
if (pos != std::string::npos) {
transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos));

for (const auto &i : l2->at(0)->getOrigin()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
origin->m_offset = i->m_offset;
origin->m_length = i->m_length;
var->addOrigin(std::move(origin));
}
l->push_back(var);
auto var = std::make_unique<VariableValue>(&v->getKeyWithCollection(),
&transaction->m_variableRemoteUser);

var->reserveOrigin(v->getOrigin().size());
for (const auto &i : v->getOrigin()) {
var->addOrigin(i);
}
l->push_back(var.release());
}

clear:
for (auto &a : *l2) {
delete a;
for (auto &a : l2) {
delete a;
}
}
l2->clear();
delete l2;
}


Expand Down
Loading
Loading