Bugfix: Require OrderedTxItems to provide properly scoped accounting entry list

OrderedTxItems returns a multimap of pointers, but needs a place to store the actual CAccountingEntries it points to.
It had been using a stack item, which was clobbered as soon as it returned, resulting in undefined behaviour.
This fixes at least bug #1768.
This commit is contained in:
Luke Dashjr 2012-09-01 22:07:47 +00:00
parent c3f95ef13f
commit ddb709e9de
3 changed files with 12 additions and 6 deletions

View file

@ -987,7 +987,8 @@ Value listtransactions(const Array& params, bool fHelp)
Array ret; Array ret;
CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(strAccount); std::list<CAccountingEntry> acentries;
CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount);
// iterate backwards until we have nCount items to return: // iterate backwards until we have nCount items to return:
for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)

View file

@ -291,8 +291,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return true; return true;
} }
CWallet::TxItems CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount)
CWallet::OrderedTxItems(std::string strAccount)
{ {
CWalletDB walletdb(strWalletFile); CWalletDB walletdb(strWalletFile);
@ -306,7 +305,7 @@ CWallet::OrderedTxItems(std::string strAccount)
CWalletTx* wtx = &((*it).second); CWalletTx* wtx = &((*it).second);
txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0)));
} }
list<CAccountingEntry> acentries; acentries.clear();
walletdb.ListAccountCreditDebit(strAccount, acentries); walletdb.ListAccountCreditDebit(strAccount, acentries);
BOOST_FOREACH(CAccountingEntry& entry, acentries) BOOST_FOREACH(CAccountingEntry& entry, acentries)
{ {
@ -375,7 +374,8 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn)
{ {
// Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future
int64 latestTolerated = latestNow + 300; int64 latestTolerated = latestNow + 300;
TxItems txOrdered = OrderedTxItems(); std::list<CAccountingEntry> acentries;
TxItems txOrdered = OrderedTxItems(acentries);
for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
{ {
CWalletTx *const pwtx = (*it).second.first; CWalletTx *const pwtx = (*it).second.first;

View file

@ -146,7 +146,12 @@ public:
typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair;
typedef std::multimap<int64, TxPair > TxItems; typedef std::multimap<int64, TxPair > TxItems;
TxItems OrderedTxItems(std::string strAccount = "");
/** Get the wallet's activity log
@return multimap of ordered transactions and accounting entries
@warning Returned pointers are *only* valid within the scope of passed acentries
*/
TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = "");
void MarkDirty(); void MarkDirty();
bool AddToWallet(const CWalletTx& wtxIn); bool AddToWallet(const CWalletTx& wtxIn);