Skip to content

Commit 833089e

Browse files
committed
Adds method resolveFirstCopy to collections
Using the copy whenever it is necessary to avoid memory leak.
1 parent 6e4226e commit 833089e

File tree

8 files changed

+131
-7
lines changed

8 files changed

+131
-7
lines changed

headers/modsecurity/collection/collection.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class Collection {
5151
virtual void del(const std::string& key) = 0;
5252

5353
virtual std::string* resolveFirst(const std::string& var) = 0;
54+
virtual std::string resolveFirstCopy(const std::string& var) = 0;
5455

5556
virtual void resolveSingleMatch(const std::string& var,
5657
std::vector<const Variable *> *l) = 0;
@@ -89,6 +90,12 @@ class Collection {
8990
return resolveFirst(nkey);
9091
}
9192

93+
virtual std::string resolveFirstCopy(const std::string& var,
94+
std::string compartment) {
95+
std::string nkey = compartment + "::" + var;
96+
return resolveFirstCopy(nkey);
97+
}
98+
9299
virtual void resolveSingleMatch(const std::string& var,
93100
std::string compartment, std::vector<const Variable *> *l) {
94101
std::string nkey = compartment + "::" + var;
@@ -102,12 +109,10 @@ class Collection {
102109
}
103110

104111
virtual void resolveRegularExpression(const std::string& var,
105-
std::string compartment,
106-
std::vector<const Variable *> *l) {
112+
std::string compartment, std::vector<const Variable *> *l) {
107113
std::string nkey = compartment + "::" + var;
108114
resolveRegularExpression(nkey, l);
109115
}
110-
111116
};
112117

113118
} // namespace collection

headers/modsecurity/collection/collections.h

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ class Collections :
5959
std::string* resolveFirst(const std::string& var);
6060
std::string* resolveFirst(const std::string& collectionName,
6161
const std::string& var);
62+
std::string resolveFirstCopy(const std::string& var);
63+
std::string resolveFirstCopy(const std::string& collectionName,
64+
const std::string& var);
6265

6366
void resolveSingleMatch(const std::string& var,
6467
std::vector<const Variable *> *l);

src/actions/set_var.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -109,14 +109,14 @@ bool SetVar::evaluate(Rule *rule, Transaction *transm_parser_payload) {
109109
}
110110

111111
try {
112-
std::string *resolvedValue =
113-
transm_parser_payload->m_collections.resolveFirst(
112+
std::string resolvedValue =
113+
transm_parser_payload->m_collections.resolveFirstCopy(
114114
m_collectionName,
115115
m_variableNameExpanded);
116-
if (resolvedValue == NULL) {
116+
if (resolvedValue.empty()) {
117117
value = 0;
118118
} else {
119-
value = stoi(*resolvedValue);
119+
value = stoi(resolvedValue);
120120
}
121121
} catch (...) {
122122
value = 0;

src/collection/backend/in_memory-per_process.cc

+11
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,17 @@ std::string* InMemoryPerProcess::resolveFirst(const std::string& var) {
123123
}
124124

125125

126+
std::string InMemoryPerProcess::resolveFirstCopy(const std::string& var) {
127+
auto range = equal_range(var);
128+
129+
for (auto it = range.first; it != range.second; ++it) {
130+
return it->second;
131+
}
132+
133+
return "";
134+
}
135+
136+
126137
} // namespace backend
127138
} // namespace collection
128139
} // namespace modsecurity

src/collection/backend/in_memory-per_process.h

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class InMemoryPerProcess :
8383
void del(const std::string& key) override;
8484

8585
std::string* resolveFirst(const std::string& var) override;
86+
std::string resolveFirstCopy(const std::string& var) override;
8687

8788
void resolveSingleMatch(const std::string& var,
8889
std::vector<const Variable *> *l) override;

src/collection/backend/lmdb.cc

+41
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,47 @@ void LMDB::lmdb_debug(int rc, std::string op, std::string scope) {
155155
#endif
156156
}
157157

158+
159+
std::string LMDB::resolveFirstCopy(const std::string& var) {
160+
int rc;
161+
MDB_val mdb_key;
162+
MDB_val mdb_value;
163+
MDB_val mdb_value_ret;
164+
std::string ret;
165+
MDB_txn *txn = NULL;
166+
MDB_dbi dbi;
167+
168+
string2val(var, &mdb_key);
169+
170+
rc = mdb_txn_begin(m_env, NULL, 0, &txn);
171+
lmdb_debug(rc, "txn", "resolveFirst");
172+
if (rc != 0) {
173+
goto end_txn;
174+
}
175+
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
176+
lmdb_debug(rc, "dbi", "resolveFirst");
177+
if (rc != 0) {
178+
goto end_dbi;
179+
}
180+
rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret);
181+
lmdb_debug(rc, "get", "resolveFirst");
182+
if (rc != 0) {
183+
goto end_get;
184+
}
185+
186+
ret.assign(
187+
reinterpret_cast<char *>(mdb_value_ret.mv_data),
188+
mdb_value_ret.mv_size);
189+
190+
end_get:
191+
mdb_dbi_close(m_env, dbi);
192+
end_dbi:
193+
mdb_txn_abort(txn);
194+
end_txn:
195+
return ret;
196+
}
197+
198+
158199
std::string* LMDB::resolveFirst(const std::string& var) {
159200
int rc;
160201
MDB_val mdb_key;

src/collection/backend/lmdb.h

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class LMDB :
5757
void del(const std::string& key) override;
5858

5959
std::string* resolveFirst(const std::string& var) override;
60+
std::string resolveFirstCopy(const std::string& var) override;
6061

6162
void resolveSingleMatch(const std::string& var,
6263
std::vector<const Variable *> *l) override;

src/collection/collections.cc

+62
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,68 @@ std::string* Collections::resolveFirst(const std::string& collectionName,
183183
}
184184

185185

186+
std::string Collections::resolveFirstCopy(const std::string& var) {
187+
std::string transientVar = m_transient->resolveFirstCopy(var);
188+
189+
if (transientVar.empty() == false) {
190+
return transientVar;
191+
}
192+
193+
for (auto &a : *this) {
194+
std::string res = a.second->resolveFirstCopy(toupper(a.first) +
195+
":" + var);
196+
if (res.empty() == false) {
197+
return res;
198+
}
199+
}
200+
201+
return "";
202+
}
203+
204+
205+
std::string Collections::resolveFirstCopy(const std::string& collectionName,
206+
const std::string& var) {
207+
if (tolower(collectionName) == "ip"
208+
&& !m_ip_collection_key.empty()) {
209+
return m_ip_collection->resolveFirstCopy(toupper(collectionName)
210+
+ ":" + var, m_ip_collection_key);
211+
}
212+
213+
if (tolower(collectionName) == "global"
214+
&& !m_global_collection_key.empty()) {
215+
return m_global_collection->resolveFirstCopy(
216+
toupper(collectionName) + ":" + var,
217+
m_global_collection_key);
218+
}
219+
220+
if (tolower(collectionName) == "resource"
221+
&& !m_resource_collection_key.empty()) {
222+
return m_resource_collection->resolveFirstCopy(
223+
toupper(collectionName) + ":" + var,
224+
m_resource_collection_key);
225+
}
226+
227+
if (tolower(collectionName) == "session"
228+
&& !m_session_collection_key.empty()) {
229+
return m_session_collection->resolveFirstCopy(
230+
toupper(collectionName) + ":" + var,
231+
m_session_collection_key);
232+
}
233+
234+
for (auto &a : *this) {
235+
if (tolower(a.first) == tolower(collectionName)) {
236+
std::string res = a.second->resolveFirstCopy(toupper(a.first)
237+
+ ":" + var);
238+
if (res.empty() == false) {
239+
return res;
240+
}
241+
}
242+
}
243+
244+
return "";
245+
}
246+
247+
186248
void Collections::resolveSingleMatch(const std::string& var,
187249
std::vector<const Variable *> *l) {
188250

0 commit comments

Comments
 (0)