diff options
| author | xiphon <xiphon@protonmail.com> | 2019-12-16 07:50:01 +0000 |
|---|---|---|
| committer | xiphon <xiphon@protonmail.com> | 2019-12-16 13:31:31 +0000 |
| commit | 4e1f7349c459c9e0b45bb7fa68d10ce05158e7fb (patch) | |
| tree | adda7d6a019f9ecee6b10f79ba508f3f11a1dabe /src/model | |
| parent | 46227bdad08e191d54e49813ee2f4c0e3c226f95 (diff) | |
| download | monzero-gui-4e1f7349c459c9e0b45bb7fa68d10ce05158e7fb.tar.gz monzero-gui-4e1f7349c459c9e0b45bb7fa68d10ce05158e7fb.tar.xz monzero-gui-4e1f7349c459c9e0b45bb7fa68d10ce05158e7fb.zip | |
TransactionHistory: fix use-after-free bugs
Diffstat (limited to 'src/model')
| -rw-r--r-- | src/model/TransactionHistoryModel.cpp | 129 | ||||
| -rw-r--r-- | src/model/TransactionHistoryModel.h | 6 |
2 files changed, 60 insertions, 75 deletions
diff --git a/src/model/TransactionHistoryModel.cpp b/src/model/TransactionHistoryModel.cpp index c092fe8a..d3090d8c 100644 --- a/src/model/TransactionHistoryModel.cpp +++ b/src/model/TransactionHistoryModel.cpp @@ -59,106 +59,90 @@ TransactionHistory *TransactionHistoryModel::transactionHistory() const return m_transactionHistory; } -QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const +QVariant TransactionHistoryModel::parseTransactionInfo(const TransactionInfo &tInfo, int role) const { - if (!m_transactionHistory) { - return QVariant(); - } - - if (index.row() < 0 || (unsigned)index.row() >= m_transactionHistory->count()) { - return QVariant(); - } - - TransactionInfo * tInfo = m_transactionHistory->transaction(index.row()); - - - Q_ASSERT(tInfo); - if (!tInfo) { - qCritical("%s: internal error: no transaction info for index %d", __FUNCTION__, index.row()); - return QVariant(); - } - QVariant result; - switch (role) { - case TransactionRole: - result = QVariant::fromValue(tInfo); - break; + switch (role) + { case TransactionDirectionRole: - result = QVariant::fromValue(tInfo->direction()); - break; + return QVariant::fromValue(tInfo.direction()); case TransactionPendingRole: - result = tInfo->isPending(); - break; + return tInfo.isPending(); case TransactionFailedRole: - result = tInfo->isFailed(); - break; + return tInfo.isFailed(); case TransactionAmountRole: - result = tInfo->amount(); - break; + return tInfo.amount(); case TransactionDisplayAmountRole: - result = tInfo->displayAmount(); - break; + return tInfo.displayAmount(); case TransactionAtomicAmountRole: - result = tInfo->atomicAmount(); - break; + return tInfo.atomicAmount(); case TransactionFeeRole: - result = tInfo->fee(); - break; + return tInfo.fee(); case TransactionBlockHeightRole: + { // Use NULL QVariant for transactions without height. // Forces them to be displayed at top when sorted by blockHeight. - if (tInfo->blockHeight() != 0) { - result = tInfo->blockHeight(); + if (tInfo.blockHeight() != 0) + { + return tInfo.blockHeight(); } - break; - + return QVariant(); + } case TransactionSubaddrIndexRole: + { + QString str = QString{""}; + bool first = true; + for (quint32 i : tInfo.subaddrIndex()) { - QString str = QString{""}; - bool first = true; - for (quint32 i : tInfo->subaddrIndex()) { - if (!first) - str += QString{","}; - first = false; - str += QString::number(i); - } - result = str; + if (!first) + str += QString{","}; + first = false; + str += QString::number(i); } - break; + return str; + } case TransactionSubaddrAccountRole: - result = tInfo->subaddrAccount(); - break; + return tInfo.subaddrAccount(); case TransactionLabelRole: - result = tInfo->subaddrIndex().size() == 1 && *tInfo->subaddrIndex().begin() == 0 ? tr("Primary address") : tInfo->label(); - break; + return tInfo.subaddrIndex().size() == 1 && *tInfo.subaddrIndex().begin() == 0 ? tr("Primary address") : tInfo.label(); case TransactionConfirmationsRole: - result = tInfo->confirmations(); - break; + return tInfo.confirmations(); case TransactionConfirmationsRequiredRole: - result = (tInfo->blockHeight() < tInfo->unlockTime()) ? tInfo->unlockTime() - tInfo->blockHeight() : 10; - break; + return (tInfo.blockHeight() < tInfo.unlockTime()) ? tInfo.unlockTime() - tInfo.blockHeight() : 10; case TransactionHashRole: - result = tInfo->hash(); - break; + return tInfo.hash(); case TransactionTimeStampRole: - result = tInfo->timestamp(); - break; + return tInfo.timestamp(); case TransactionPaymentIdRole: - result = tInfo->paymentId(); - break; + return tInfo.paymentId(); case TransactionIsOutRole: - result = tInfo->direction() == TransactionInfo::Direction_Out; - break; + return tInfo.direction() == TransactionInfo::Direction_Out; case TransactionDateRole: - result = tInfo->date(); - break; + return tInfo.date(); case TransactionTimeRole: - result = tInfo->time(); - break; + return tInfo.time(); case TransactionDestinationsRole: - result = tInfo->destinations_formatted(); - break; + return tInfo.destinations_formatted(); + default: + { + qCritical() << "Unimplemented role" << role; + return QVariant(); } + } +} +QVariant TransactionHistoryModel::data(const QModelIndex &index, int role) const +{ + if (!m_transactionHistory) { + return QVariant(); + } + + QVariant result; + bool found = m_transactionHistory->transaction(index.row(), [this, &result, &role](const TransactionInfo &tInfo) { + result = parseTransactionInfo(tInfo, role); + }); + if (!found) { + qCritical("%s: internal error: no transaction info for index %d", __FUNCTION__, index.row()); + } return result; } @@ -171,7 +155,6 @@ int TransactionHistoryModel::rowCount(const QModelIndex &parent) const QHash<int, QByteArray> TransactionHistoryModel::roleNames() const { QHash<int, QByteArray> roleNames = QAbstractListModel::roleNames(); - roleNames.insert(TransactionRole, "transaction"); roleNames.insert(TransactionDirectionRole, "direction"); roleNames.insert(TransactionPendingRole, "isPending"); roleNames.insert(TransactionFailedRole, "isFailed"); diff --git a/src/model/TransactionHistoryModel.h b/src/model/TransactionHistoryModel.h index 578a803e..8b3bae86 100644 --- a/src/model/TransactionHistoryModel.h +++ b/src/model/TransactionHistoryModel.h @@ -45,8 +45,7 @@ class TransactionHistoryModel : public QAbstractListModel public: enum TransactionInfoRole { - TransactionRole = Qt::UserRole + 1, // for the TransactionInfo object; - TransactionDirectionRole, + TransactionDirectionRole = Qt::UserRole + 1, TransactionPendingRole, TransactionFailedRole, TransactionAmountRole, @@ -98,6 +97,9 @@ signals: void transactionHistoryChanged(); private: + QVariant parseTransactionInfo(const TransactionInfo &tInfo, int role) const; + +private: TransactionHistory * m_transactionHistory; }; |
