aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/db.cpp
diff options
context:
space:
mode:
authorJoão Barbosa <joao.paulo.barbosa@gmail.com>2017-10-12 23:14:46 +0100
committerJoão Barbosa <joao.paulo.barbosa@gmail.com>2017-10-14 23:59:46 +0100
commit7104de8b1f3a31d3a60009b5dc376adbedac6a9c (patch)
tree827a41ec17d3d3e887f236848f122fcf3cdb7832 /src/wallet/db.cpp
parent326a5652e0d25fdb60c337ef4f1c98a63e0748f0 (diff)
downloadbitcoin-7104de8b1f3a31d3a60009b5dc376adbedac6a9c.tar.xz
[wallet] Fix leak in CDB constructor
Now using a std::unique_ptr, the Db instance is correctly released when CDB initialization fails. The internal CDB state and mapFileUseCount are only mutated when the CDB initialization succeeds.
Diffstat (limited to 'src/wallet/db.cpp')
-rw-r--r--src/wallet/db.cpp34
1 files changed, 16 insertions, 18 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index d66ba48421..5e881d9acc 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -379,45 +379,43 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
if (!env->Open(GetDataDir()))
throw std::runtime_error("CDB: Failed to open database environment.");
- strFile = strFilename;
- ++env->mapFileUseCount[strFile];
- pdb = env->mapDb[strFile];
+ pdb = env->mapDb[strFilename];
if (pdb == nullptr) {
int ret;
- pdb = new Db(env->dbenv, 0);
+ std::unique_ptr<Db> pdb_temp(new Db(env->dbenv, 0));
bool fMockDb = env->IsMock();
if (fMockDb) {
- DbMpoolFile* mpf = pdb->get_mpf();
+ DbMpoolFile* mpf = pdb_temp->get_mpf();
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
- if (ret != 0)
- throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile));
+ if (ret != 0) {
+ throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFilename));
+ }
}
- ret = pdb->open(nullptr, // Txn pointer
- fMockDb ? nullptr : strFile.c_str(), // Filename
- fMockDb ? strFile.c_str() : "main", // Logical db name
- DB_BTREE, // Database type
- nFlags, // Flags
+ ret = pdb_temp->open(nullptr, // Txn pointer
+ fMockDb ? nullptr : strFilename.c_str(), // Filename
+ fMockDb ? strFilename.c_str() : "main", // Logical db name
+ DB_BTREE, // Database type
+ nFlags, // Flags
0);
if (ret != 0) {
- delete pdb;
- pdb = nullptr;
- --env->mapFileUseCount[strFile];
- strFile = "";
throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename));
}
+ pdb = pdb_temp.release();
+ env->mapDb[strFilename] = pdb;
+
if (fCreate && !Exists(std::string("version"))) {
bool fTmp = fReadOnly;
fReadOnly = false;
WriteVersion(CLIENT_VERSION);
fReadOnly = fTmp;
}
-
- env->mapDb[strFile] = pdb;
}
+ ++env->mapFileUseCount[strFilename];
+ strFile = strFilename;
}
}