Skip to content

Commit 7104de8

Browse files
committed
[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.
1 parent 326a565 commit 7104de8

File tree

1 file changed

+16
-18
lines changed

1 file changed

+16
-18
lines changed

src/wallet/db.cpp

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -379,45 +379,43 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
379379
if (!env->Open(GetDataDir()))
380380
throw std::runtime_error("CDB: Failed to open database environment.");
381381

382-
strFile = strFilename;
383-
++env->mapFileUseCount[strFile];
384-
pdb = env->mapDb[strFile];
382+
pdb = env->mapDb[strFilename];
385383
if (pdb == nullptr) {
386384
int ret;
387-
pdb = new Db(env->dbenv, 0);
385+
std::unique_ptr<Db> pdb_temp(new Db(env->dbenv, 0));
388386

389387
bool fMockDb = env->IsMock();
390388
if (fMockDb) {
391-
DbMpoolFile* mpf = pdb->get_mpf();
389+
DbMpoolFile* mpf = pdb_temp->get_mpf();
392390
ret = mpf->set_flags(DB_MPOOL_NOFILE, 1);
393-
if (ret != 0)
394-
throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFile));
391+
if (ret != 0) {
392+
throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFilename));
393+
}
395394
}
396395

397-
ret = pdb->open(nullptr, // Txn pointer
398-
fMockDb ? nullptr : strFile.c_str(), // Filename
399-
fMockDb ? strFile.c_str() : "main", // Logical db name
400-
DB_BTREE, // Database type
401-
nFlags, // Flags
396+
ret = pdb_temp->open(nullptr, // Txn pointer
397+
fMockDb ? nullptr : strFilename.c_str(), // Filename
398+
fMockDb ? strFilename.c_str() : "main", // Logical db name
399+
DB_BTREE, // Database type
400+
nFlags, // Flags
402401
0);
403402

404403
if (ret != 0) {
405-
delete pdb;
406-
pdb = nullptr;
407-
--env->mapFileUseCount[strFile];
408-
strFile = "";
409404
throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename));
410405
}
411406

407+
pdb = pdb_temp.release();
408+
env->mapDb[strFilename] = pdb;
409+
412410
if (fCreate && !Exists(std::string("version"))) {
413411
bool fTmp = fReadOnly;
414412
fReadOnly = false;
415413
WriteVersion(CLIENT_VERSION);
416414
fReadOnly = fTmp;
417415
}
418-
419-
env->mapDb[strFile] = pdb;
420416
}
417+
++env->mapFileUseCount[strFilename];
418+
strFile = strFilename;
421419
}
422420
}
423421

0 commit comments

Comments
 (0)