aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/db.cpp
diff options
context:
space:
mode:
authorBen Woosley <ben.woosley@gmail.com>2018-09-19 02:38:40 -0400
committerBen Woosley <ben.woosley@gmail.com>2018-11-12 18:43:52 -0500
commit1a9f9f7e5e2e73fb832f5b96ad7e9e57954f3f3c (patch)
tree0604ef70ee47416fd3603cbed6243b921a0ba14c /src/wallet/db.cpp
parent951a44e9cd6cf2b8058244f3f95181c5ba683fdd (diff)
Introduce SafeDbt to handle DB_DBT_MALLOC raii-style
This provides additional exception-safety and case handling for the proper freeing of the associated buffers.
Diffstat (limited to 'src/wallet/db.cpp')
-rw-r--r--src/wallet/db.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index a7bf89c572..9bac3c49cc 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -247,6 +247,45 @@ BerkeleyEnvironment::VerifyResult BerkeleyEnvironment::Verify(const std::string&
return (fRecovered ? VerifyResult::RECOVER_OK : VerifyResult::RECOVER_FAIL);
}
+BerkeleyBatch::SafeDbt::SafeDbt(u_int32_t flags)
+{
+ m_dbt.set_flags(flags);
+}
+
+BerkeleyBatch::SafeDbt::SafeDbt(void *data, size_t size)
+ : m_dbt(data, size)
+{
+}
+
+BerkeleyBatch::SafeDbt::~SafeDbt()
+{
+ if (m_dbt.get_data() != nullptr) {
+ // Clear memory, e.g. in case it was a private key
+ memory_cleanse(m_dbt.get_data(), m_dbt.get_size());
+ // under DB_DBT_MALLOC, data is malloced by the Dbt, but must be
+ // freed by the caller.
+ // https://docs.oracle.com/cd/E17275_01/html/api_reference/C/dbt.html
+ if (m_dbt.get_flags() & DB_DBT_MALLOC) {
+ free(m_dbt.get_data());
+ }
+ }
+}
+
+const void* BerkeleyBatch::SafeDbt::get_data() const
+{
+ return m_dbt.get_data();
+}
+
+u_int32_t BerkeleyBatch::SafeDbt::get_size() const
+{
+ return m_dbt.get_size();
+}
+
+BerkeleyBatch::SafeDbt::operator Dbt*()
+{
+ return &m_dbt;
+}
+
bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename)
{
std::string filename;