Adds method resolveFirstCopy to collections

Using the copy whenever it is necessary to avoid memory leak.
This commit is contained in:
Felipe Zimmerle 2016-07-08 10:22:37 -03:00
parent 6e4226ee4d
commit 833089eb70
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
8 changed files with 131 additions and 7 deletions

View File

@ -51,6 +51,7 @@ class Collection {
virtual void del(const std::string& key) = 0;
virtual std::string* resolveFirst(const std::string& var) = 0;
virtual std::string resolveFirstCopy(const std::string& var) = 0;
virtual void resolveSingleMatch(const std::string& var,
std::vector<const Variable *> *l) = 0;
@ -89,6 +90,12 @@ class Collection {
return resolveFirst(nkey);
}
virtual std::string resolveFirstCopy(const std::string& var,
std::string compartment) {
std::string nkey = compartment + "::" + var;
return resolveFirstCopy(nkey);
}
virtual void resolveSingleMatch(const std::string& var,
std::string compartment, std::vector<const Variable *> *l) {
std::string nkey = compartment + "::" + var;
@ -102,12 +109,10 @@ class Collection {
}
virtual void resolveRegularExpression(const std::string& var,
std::string compartment,
std::vector<const Variable *> *l) {
std::string compartment, std::vector<const Variable *> *l) {
std::string nkey = compartment + "::" + var;
resolveRegularExpression(nkey, l);
}
};
} // namespace collection

View File

@ -59,6 +59,9 @@ class Collections :
std::string* resolveFirst(const std::string& var);
std::string* resolveFirst(const std::string& collectionName,
const std::string& var);
std::string resolveFirstCopy(const std::string& var);
std::string resolveFirstCopy(const std::string& collectionName,
const std::string& var);
void resolveSingleMatch(const std::string& var,
std::vector<const Variable *> *l);

View File

@ -109,14 +109,14 @@ bool SetVar::evaluate(Rule *rule, Transaction *transm_parser_payload) {
}
try {
std::string *resolvedValue =
transm_parser_payload->m_collections.resolveFirst(
std::string resolvedValue =
transm_parser_payload->m_collections.resolveFirstCopy(
m_collectionName,
m_variableNameExpanded);
if (resolvedValue == NULL) {
if (resolvedValue.empty()) {
value = 0;
} else {
value = stoi(*resolvedValue);
value = stoi(resolvedValue);
}
} catch (...) {
value = 0;

View File

@ -123,6 +123,17 @@ std::string* InMemoryPerProcess::resolveFirst(const std::string& var) {
}
std::string InMemoryPerProcess::resolveFirstCopy(const std::string& var) {
auto range = equal_range(var);
for (auto it = range.first; it != range.second; ++it) {
return it->second;
}
return "";
}
} // namespace backend
} // namespace collection
} // namespace modsecurity

View File

@ -83,6 +83,7 @@ class InMemoryPerProcess :
void del(const std::string& key) override;
std::string* resolveFirst(const std::string& var) override;
std::string resolveFirstCopy(const std::string& var) override;
void resolveSingleMatch(const std::string& var,
std::vector<const Variable *> *l) override;

View File

@ -155,6 +155,47 @@ void LMDB::lmdb_debug(int rc, std::string op, std::string scope) {
#endif
}
std::string LMDB::resolveFirstCopy(const std::string& var) {
int rc;
MDB_val mdb_key;
MDB_val mdb_value;
MDB_val mdb_value_ret;
std::string ret;
MDB_txn *txn = NULL;
MDB_dbi dbi;
string2val(var, &mdb_key);
rc = mdb_txn_begin(m_env, NULL, 0, &txn);
lmdb_debug(rc, "txn", "resolveFirst");
if (rc != 0) {
goto end_txn;
}
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "resolveFirst");
if (rc != 0) {
goto end_dbi;
}
rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "resolveFirst");
if (rc != 0) {
goto end_get;
}
ret.assign(
reinterpret_cast<char *>(mdb_value_ret.mv_data),
mdb_value_ret.mv_size);
end_get:
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn);
end_txn:
return ret;
}
std::string* LMDB::resolveFirst(const std::string& var) {
int rc;
MDB_val mdb_key;

View File

@ -57,6 +57,7 @@ class LMDB :
void del(const std::string& key) override;
std::string* resolveFirst(const std::string& var) override;
std::string resolveFirstCopy(const std::string& var) override;
void resolveSingleMatch(const std::string& var,
std::vector<const Variable *> *l) override;

View File

@ -183,6 +183,68 @@ std::string* Collections::resolveFirst(const std::string& collectionName,
}
std::string Collections::resolveFirstCopy(const std::string& var) {
std::string transientVar = m_transient->resolveFirstCopy(var);
if (transientVar.empty() == false) {
return transientVar;
}
for (auto &a : *this) {
std::string res = a.second->resolveFirstCopy(toupper(a.first) +
":" + var);
if (res.empty() == false) {
return res;
}
}
return "";
}
std::string Collections::resolveFirstCopy(const std::string& collectionName,
const std::string& var) {
if (tolower(collectionName) == "ip"
&& !m_ip_collection_key.empty()) {
return m_ip_collection->resolveFirstCopy(toupper(collectionName)
+ ":" + var, m_ip_collection_key);
}
if (tolower(collectionName) == "global"
&& !m_global_collection_key.empty()) {
return m_global_collection->resolveFirstCopy(
toupper(collectionName) + ":" + var,
m_global_collection_key);
}
if (tolower(collectionName) == "resource"
&& !m_resource_collection_key.empty()) {
return m_resource_collection->resolveFirstCopy(
toupper(collectionName) + ":" + var,
m_resource_collection_key);
}
if (tolower(collectionName) == "session"
&& !m_session_collection_key.empty()) {
return m_session_collection->resolveFirstCopy(
toupper(collectionName) + ":" + var,
m_session_collection_key);
}
for (auto &a : *this) {
if (tolower(a.first) == tolower(collectionName)) {
std::string res = a.second->resolveFirstCopy(toupper(a.first)
+ ":" + var);
if (res.empty() == false) {
return res;
}
}
}
return "";
}
void Collections::resolveSingleMatch(const std::string& var,
std::vector<const Variable *> *l) {