Skip to content

Commit

Permalink
Merge pull request #2602 from LMDB/issue2601
Browse files Browse the repository at this point in the history
Fix #2601 misuses of LMDB API
  • Loading branch information
martinhsv authored Feb 9, 2022
2 parents 4e37985 + a6e1074 commit d0813fe
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 107 deletions.
132 changes: 25 additions & 107 deletions src/collection/backend/lmdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ namespace backend {

LMDB::LMDB(std::string name) :
Collection(name), m_env(NULL) {
MDB_txn *txn;
mdb_env_create(&m_env);
mdb_env_open(m_env, "./modsec-shared-collections",
MDB_WRITEMAP | MDB_NOSUBDIR, 0664);
mdb_txn_begin(m_env, NULL, 0, &txn);
mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &m_dbi);
mdb_txn_commit(txn);
}


Expand Down Expand Up @@ -89,23 +93,6 @@ void LMDB::lmdb_debug(int rc, std::string op, std::string scope) {
break;
}
std::cout << std::endl;
} else if (op == "dbi") {
std::cout << scope << ", LMDB failure while opening dbi: ";
switch (rc) {
case MDB_NOTFOUND:
std::cout << "not found: the specified database doesn't ";
std::cout << "exist in the environment and MDB_CREATE was ";
std::cout << "not specified.";
break;
case MDB_DBS_FULL:
std::cout << "full: too many databases have been opened. See ";
std::cout << "mdb_env_set_maxdbs().";
break;
default:
std::cout << "not sure what is wrong.";
break;
}
std::cout << std::endl;
} else if (op == "get") {
std::cout << scope << ", LMDB failure while getting the key: ";
switch (rc) {
Expand Down Expand Up @@ -169,21 +156,15 @@ std::unique_ptr<std::string> LMDB::resolveFirst(const std::string& var) {
MDB_val mdb_value_ret;
std::unique_ptr<std::string> ret = NULL;
MDB_txn *txn = NULL;
MDB_dbi dbi;

string2val(var, &mdb_key);

rc = mdb_txn_begin(m_env, NULL, 0, &txn);
rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &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);
rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "resolveFirst");
if (rc != 0) {
goto end_get;
Expand All @@ -194,8 +175,6 @@ std::unique_ptr<std::string> LMDB::resolveFirst(const std::string& var) {
mdb_value_ret.mv_size));

end_get:
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn);
end_txn:
return ret;
Expand All @@ -206,7 +185,6 @@ bool LMDB::storeOrUpdateFirst(const std::string &key,
const std::string &value) {
int rc;
MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key;
MDB_val mdb_value;
MDB_val mdb_value_ret;
Expand All @@ -220,23 +198,17 @@ bool LMDB::storeOrUpdateFirst(const std::string &key,
goto end_txn;
}

rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "storeOrUpdateFirst");
if (rc != 0) {
goto end_dbi;
}

rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret);
rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "storeOrUpdateFirst");
if (rc == 0) {
rc = mdb_del(txn, dbi, &mdb_key, &mdb_value_ret);
rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "del", "storeOrUpdateFirst");
if (rc != 0) {
goto end_del;
}
}

rc = mdb_put(txn, dbi, &mdb_key, &mdb_value, 0);
rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0);
lmdb_debug(rc, "put", "storeOrUpdateFirst");
if (rc != 0) {
goto end_put;
Expand All @@ -248,14 +220,12 @@ bool LMDB::storeOrUpdateFirst(const std::string &key,
goto end_commit;
}

end_commit:
end_put:
end_del:
mdb_dbi_close(m_env, dbi);
end_dbi:
if (rc != 0) {
mdb_txn_abort(txn);
}
end_commit:
end_txn:
return true;
}
Expand All @@ -265,26 +235,20 @@ void LMDB::resolveSingleMatch(const std::string& var,
std::vector<const VariableValue *> *l) {
int rc;
MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key;
MDB_val mdb_value;
MDB_val mdb_value_ret;
MDB_cursor *cursor;

rc = mdb_txn_begin(m_env, NULL, 0, &txn);
rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn);
lmdb_debug(rc, "txn", "resolveSingleMatch");
if (rc != 0) {
goto end_txn;
}
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "resolveSingleMatch");
if (rc != 0) {
goto end_dbi;
}

string2val(var, &mdb_key);

mdb_cursor_open(txn, dbi, &cursor);
mdb_cursor_open(txn, m_dbi, &cursor);
while ((rc = mdb_cursor_get(cursor, &mdb_key,
&mdb_value_ret, MDB_NEXT_DUP)) == 0) {
std::string *a = new std::string(
Expand All @@ -295,9 +259,6 @@ void LMDB::resolveSingleMatch(const std::string& var,
}

mdb_cursor_close(cursor);

mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn);
end_txn:
return;
Expand All @@ -307,7 +268,6 @@ void LMDB::resolveSingleMatch(const std::string& var,
void LMDB::store(std::string key, std::string value) {
MDB_val mdb_key, mdb_data;
MDB_txn *txn = NULL;
MDB_dbi dbi;
int rc;
MDB_stat mst;

Expand All @@ -316,15 +276,10 @@ void LMDB::store(std::string key, std::string value) {
if (rc != 0) {
goto end_txn;
}
rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "store");
if (rc != 0) {
goto end_dbi;
}

string2val(key, &mdb_key);
string2val(value, &mdb_data);
rc = mdb_put(txn, dbi, &mdb_key, &mdb_data, 0);
rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_data, 0);
lmdb_debug(rc, "put", "store");
if (rc != 0) {
goto end_put;
Expand All @@ -336,13 +291,12 @@ void LMDB::store(std::string key, std::string value) {
goto end_commit;
}

end_commit:
end_put:
mdb_dbi_close(m_env, dbi);
end_dbi:
if (rc != 0) {
mdb_txn_abort(txn);
}
end_commit:
end_txn:
return;
}
Expand All @@ -352,7 +306,6 @@ bool LMDB::updateFirst(const std::string &key,
const std::string &value) {
int rc;
MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key;
MDB_val mdb_value;
MDB_val mdb_value_ret;
Expand All @@ -363,28 +316,22 @@ bool LMDB::updateFirst(const std::string &key,
goto end_txn;
}

rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "updateFirst");
if (rc != 0) {
goto end_dbi;
}

string2val(key, &mdb_key);
string2val(value, &mdb_value);

rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret);
rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "updateFirst");
if (rc != 0) {
goto end_get;
}

rc = mdb_del(txn, dbi, &mdb_key, &mdb_value_ret);
rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "del", "updateFirst");
if (rc != 0) {
goto end_del;
}

rc = mdb_put(txn, dbi, &mdb_key, &mdb_value, 0);
rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0);
lmdb_debug(rc, "put", "updateFirst");
if (rc != 0) {
goto end_put;
Expand All @@ -396,15 +343,13 @@ bool LMDB::updateFirst(const std::string &key,
goto end_commit;
}

end_commit:
end_put:
end_del:
end_get:
mdb_dbi_close(m_env, dbi);
end_dbi:
if (rc != 0) {
mdb_txn_abort(txn);
}
end_commit:
end_txn:

return rc == 0;
Expand All @@ -414,7 +359,6 @@ bool LMDB::updateFirst(const std::string &key,
void LMDB::del(const std::string& key) {
int rc;
MDB_txn *txn;
MDB_dbi dbi;
MDB_val mdb_key;
MDB_val mdb_value;
MDB_val mdb_value_ret;
Expand All @@ -426,21 +370,15 @@ void LMDB::del(const std::string& key) {
goto end_txn;
}

rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "del");
if (rc != 0) {
goto end_dbi;
}

string2val(key, &mdb_key);

rc = mdb_get(txn, dbi, &mdb_key, &mdb_value_ret);
rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "get", "del");
if (rc != 0) {
goto end_get;
}

rc = mdb_del(txn, dbi, &mdb_key, &mdb_value_ret);
rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);
lmdb_debug(rc, "del", "del");
if (rc != 0) {
goto end_del;
Expand All @@ -452,14 +390,12 @@ void LMDB::del(const std::string& key) {
goto end_commit;
}

end_commit:
end_del:
end_get:
mdb_dbi_close(m_env, dbi);
end_dbi:
if (rc != 0) {
mdb_txn_abort(txn);
}
end_commit:
end_txn:
return;
}
Expand All @@ -470,25 +406,18 @@ void LMDB::resolveMultiMatches(const std::string& var,
variables::KeyExclusions &ke) {
MDB_val key, data;
MDB_txn *txn = NULL;
MDB_dbi dbi;
int rc;
MDB_stat mst;
size_t keySize = var.size();
MDB_cursor *cursor;

rc = mdb_txn_begin(m_env, NULL, 0, &txn);
rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn);
lmdb_debug(rc, "txn", "resolveMultiMatches");
if (rc != 0) {
goto end_txn;
}

rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "resolveMultiMatches");
if (rc != 0) {
goto end_dbi;
}

rc = mdb_cursor_open(txn, dbi, &cursor);
rc = mdb_cursor_open(txn, m_dbi, &cursor);
lmdb_debug(rc, "cursor_open", "resolveMultiMatches");
if (rc != 0) {
goto end_cursor_open;
Expand Down Expand Up @@ -519,8 +448,6 @@ void LMDB::resolveMultiMatches(const std::string& var,

mdb_cursor_close(cursor);
end_cursor_open:
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn);
end_txn:
return;
Expand All @@ -532,26 +459,19 @@ void LMDB::resolveRegularExpression(const std::string& var,
variables::KeyExclusions &ke) {
MDB_val key, data;
MDB_txn *txn = NULL;
MDB_dbi dbi;
int rc;
MDB_stat mst;
MDB_cursor *cursor;

Utils::Regex r(var, true);

rc = mdb_txn_begin(m_env, NULL, 0, &txn);
rc = mdb_txn_begin(m_env, NULL, MDB_RDONLY, &txn);
lmdb_debug(rc, "txn", "resolveRegularExpression");
if (rc != 0) {
goto end_txn;
}

rc = mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &dbi);
lmdb_debug(rc, "dbi", "resolveRegularExpression");
if (rc != 0) {
goto end_dbi;
}

rc = mdb_cursor_open(txn, dbi, &cursor);
rc = mdb_cursor_open(txn, m_dbi, &cursor);
lmdb_debug(rc, "cursor_open", "resolveRegularExpression");
if (rc != 0) {
goto end_cursor_open;
Expand All @@ -578,8 +498,6 @@ void LMDB::resolveRegularExpression(const std::string& var,

mdb_cursor_close(cursor);
end_cursor_open:
mdb_dbi_close(m_env, dbi);
end_dbi:
mdb_txn_abort(txn);
end_txn:
return;
Expand Down
1 change: 1 addition & 0 deletions src/collection/backend/lmdb.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class LMDB :
void inline lmdb_debug(int rc, std::string op, std::string scope);

MDB_env *m_env;
MDB_dbi m_dbi;
};

} // namespace backend
Expand Down

0 comments on commit d0813fe

Please sign in to comment.