diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-07-30 18:13:19 +0200 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-07-30 18:13:19 +0200 |
commit | 7f3d97517f334cbc9b07100d20acb612a3293bfd (patch) | |
tree | 6f84ee2c9799d26e1faec5b66158c1420c4c2894 /src | |
parent | Add workaround for duplicate syncs (diff) | |
download | nheko-7f3d97517f334cbc9b07100d20acb612a3293bfd.tar.xz |
Fix double free by closing cursor at the right time
Diffstat (limited to 'src')
-rw-r--r-- | src/Cache.cpp | 59 |
1 files changed, 33 insertions, 26 deletions
diff --git a/src/Cache.cpp b/src/Cache.cpp index 628062a1..0c692d07 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -2199,27 +2199,31 @@ Cache::firstPendingMessage(const std::string &room_id) auto txn = lmdb::txn::begin(env_); auto pending = getPendingMessagesDb(txn, room_id); - auto pendingCursor = lmdb::cursor::open(txn, pending); - lmdb::val tsIgnored, pendingTxn; - while (pendingCursor.get(tsIgnored, pendingTxn, MDB_NEXT)) { - auto eventsDb = getEventsDb(txn, room_id); - lmdb::val event; - if (!lmdb::dbi_get(txn, eventsDb, pendingTxn, event)) { - lmdb::dbi_del(txn, pending, tsIgnored, pendingTxn); - continue; - } + { + auto pendingCursor = lmdb::cursor::open(txn, pending); + lmdb::val tsIgnored, pendingTxn; + while (pendingCursor.get(tsIgnored, pendingTxn, MDB_NEXT)) { + auto eventsDb = getEventsDb(txn, room_id); + lmdb::val event; + if (!lmdb::dbi_get(txn, eventsDb, pendingTxn, event)) { + lmdb::dbi_del(txn, pending, tsIgnored, pendingTxn); + continue; + } - try { - mtx::events::collections::TimelineEvent te; - mtx::events::collections::from_json( - json::parse(std::string_view(event.data(), event.size())), te); + try { + mtx::events::collections::TimelineEvent te; + mtx::events::collections::from_json( + json::parse(std::string_view(event.data(), event.size())), te); - txn.commit(); - return te; - } catch (std::exception &e) { - nhlog::db()->error("Failed to parse message from cache {}", e.what()); - lmdb::dbi_del(txn, pending, tsIgnored, pendingTxn); - continue; + pendingCursor.close(); + txn.commit(); + return te; + } catch (std::exception &e) { + nhlog::db()->error("Failed to parse message from cache {}", + e.what()); + lmdb::dbi_del(txn, pending, tsIgnored, pendingTxn); + continue; + } } } @@ -2231,13 +2235,16 @@ Cache::firstPendingMessage(const std::string &room_id) void Cache::removePendingStatus(const std::string &room_id, const std::string &txn_id) { - auto txn = lmdb::txn::begin(env_); - auto pending = getPendingMessagesDb(txn, room_id); - auto pendingCursor = lmdb::cursor::open(txn, pending); - lmdb::val tsIgnored, pendingTxn; - while (pendingCursor.get(tsIgnored, pendingTxn, MDB_NEXT)) { - if (std::string_view(pendingTxn.data(), pendingTxn.size()) == txn_id) - lmdb::cursor_del(pendingCursor); + auto txn = lmdb::txn::begin(env_); + auto pending = getPendingMessagesDb(txn, room_id); + + { + auto pendingCursor = lmdb::cursor::open(txn, pending); + lmdb::val tsIgnored, pendingTxn; + while (pendingCursor.get(tsIgnored, pendingTxn, MDB_NEXT)) { + if (std::string_view(pendingTxn.data(), pendingTxn.size()) == txn_id) + lmdb::cursor_del(pendingCursor); + } } txn.commit(); |