diff --git a/src/qt/editsidestakedialog.cpp b/src/qt/editsidestakedialog.cpp index 7d0904d351..2b8bc3f46f 100644 --- a/src/qt/editsidestakedialog.cpp +++ b/src/qt/editsidestakedialog.cpp @@ -138,7 +138,14 @@ void EditSideStakeDialog::accept() QMessageBox::warning(this, windowTitle(), tr("The entered allocation is not valid. Check to make sure that the " "allocation is greater than zero and when added to the other allocations " - "totals less than 100.").arg(ui->allocationLineEdit->text()), + "totals less than 100."), + QMessageBox::Ok, QMessageBox::Ok); + break; + case SideStakeTableModel::INVALID_DESCRIPTION: + QMessageBox::warning(this, windowTitle(), + tr("The entered description is not valid. Check to make sure that the " + "description only contains letters, numbers, spaces, periods, or " + "underscores."), QMessageBox::Ok, QMessageBox::Ok); } diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 776d99b473..258c69a4c7 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -194,7 +194,7 @@ void OptionsDialog::setModel(OptionsModel *model) ui->sidestakingTableView->installEventFilter(this); connect(this, &OptionsDialog::sidestakeAllocationInvalid, this, &OptionsDialog::handleSideStakeAllocationInvalid); - + connect(this, &OptionsDialog::sidestakeDescriptionInvalid, this, &OptionsDialog::handleSideStakeDescriptionInvalid); } /* update the display unit, to not use the default ("BTC") */ @@ -564,6 +564,10 @@ bool OptionsDialog::eventFilter(QObject *object, QEvent *event) if (model->getSideStakeTableModel()->getEditStatus() == SideStakeTableModel::INVALID_ALLOCATION) { emit sidestakeAllocationInvalid(); } + + if (model->getSideStakeTableModel()->getEditStatus() == SideStakeTableModel::INVALID_DESCRIPTION) { + emit sidestakeDescriptionInvalid(); + } } return QDialog::eventFilter(object, event); @@ -601,6 +605,17 @@ void OptionsDialog::handleSideStakeAllocationInvalid() QMessageBox::Ok, QMessageBox::Ok); } +void OptionsDialog::handleSideStakeDescriptionInvalid() +{ + model->getSideStakeTableModel()->refresh(); + + QMessageBox::warning(this, windowTitle(), + tr("The entered description is not valid. Check to make sure that the " + "description only contains letters, numbers, spaces, periods, or " + "underscores."), + QMessageBox::Ok, QMessageBox::Ok); +} + void OptionsDialog::updateSideStakeTableView() { ui->sidestakingTableView->update(); diff --git a/src/qt/optionsdialog.h b/src/qt/optionsdialog.h index fba67d0554..b5a879fa44 100644 --- a/src/qt/optionsdialog.h +++ b/src/qt/optionsdialog.h @@ -61,6 +61,7 @@ private slots: void handleStakingEfficiencyValid(QValidatedLineEdit *object, bool fState); void handleMinStakeSplitValueValid(QValidatedLineEdit *object, bool fState); void handleSideStakeAllocationInvalid(); + void handleSideStakeDescriptionInvalid(); void refreshSideStakeTableModel(); @@ -71,6 +72,7 @@ private slots: void stakingEfficiencyValid(QValidatedLineEdit *object, bool fValid); void minStakeSplitValueValid(QValidatedLineEdit *object, bool fValid); void sidestakeAllocationInvalid(); + void sidestakeDescriptionInvalid(); private: Ui::OptionsDialog *ui; @@ -89,8 +91,8 @@ private slots: enum SideStakeTableColumnWidths { ADDRESS_COLUMN_WIDTH = 200, - ALLOCATION_COLUMN_WIDTH = 50, - DESCRIPTION_COLUMN_WIDTH = 130, + ALLOCATION_COLUMN_WIDTH = 60, + DESCRIPTION_COLUMN_WIDTH = 150, STATUS_COLUMN_WIDTH = 50 }; diff --git a/src/qt/sidestaketablemodel.cpp b/src/qt/sidestaketablemodel.cpp index c3df02df21..9beabbdf78 100644 --- a/src/qt/sidestaketablemodel.cpp +++ b/src/qt/sidestaketablemodel.cpp @@ -247,11 +247,19 @@ bool SideStakeTableModel::setData(const QModelIndex &index, const QVariant &valu } case Description: { - if (rec->m_description == value.toString().toStdString()) { + std::string orig_value = value.toString().toStdString(); + std::string san_value = SanitizeString(orig_value, SAFE_CHARS_CSV); + + if (rec->m_description == orig_value) { m_edit_status = NO_CHANGES; return false; } + if (san_value != orig_value) { + m_edit_status = INVALID_DESCRIPTION; + return false; + } + // Save the original local sidestake (also in the core). GRC::SideStake orig_sidestake = *rec; @@ -261,7 +269,7 @@ bool SideStakeTableModel::setData(const QModelIndex &index, const QVariant &valu // Add back the sidestake with the modified allocation registry.NonContractAdd(GRC::SideStake(orig_sidestake.m_key, orig_sidestake.m_allocation, - value.toString().toStdString(), + san_value, int64_t {0}, uint256 {}, orig_sidestake.m_status.Value()), true); @@ -327,8 +335,6 @@ QString SideStakeTableModel::addRow(const QString &address, const QString &alloc double sidestake_allocation = 0.0; - std::string sidestake_description = description.toStdString(); - m_edit_status = OK; if (!sidestake_address.IsValid()) { @@ -362,9 +368,17 @@ QString SideStakeTableModel::addRow(const QString &address, const QString &alloc sidestake_allocation /= 100.0; + std::string sidestake_description = description.toStdString(); + std::string sanitized_description = SanitizeString(sidestake_description, SAFE_CHARS_CSV); + + if (sanitized_description != sidestake_description) { + m_edit_status = INVALID_DESCRIPTION; + return QString(); + } + registry.NonContractAdd(GRC::SideStake(sidestake_address, sidestake_allocation, - sidestake_description, + sanitized_description, int64_t {0}, uint256 {}, GRC::SideStakeStatus::ACTIVE)); diff --git a/src/qt/sidestaketablemodel.h b/src/qt/sidestaketablemodel.h index 5bbe0f69f9..60320c36f3 100644 --- a/src/qt/sidestaketablemodel.h +++ b/src/qt/sidestaketablemodel.h @@ -58,7 +58,8 @@ class SideStakeTableModel : public QAbstractTableModel NO_CHANGES, /**< No changes were made during edit operation */ INVALID_ADDRESS, /**< Unparseable address */ DUPLICATE_ADDRESS, /**< Address already in sidestake registry */ - INVALID_ALLOCATION /**< Allocation is invalid (i.e. not parseable or not between 0.0 and 100.0) */ + INVALID_ALLOCATION, /**< Allocation is invalid (i.e. not parseable or not between 0.0 and 100.0) */ + INVALID_DESCRIPTION /**< Description contains an invalid character */ }; /** @name Methods overridden from QAbstractTableModel diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 34fe5f2aba..db89881f26 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -21,6 +21,7 @@ static const std::string SAFE_CHARS[] = CHARS_ALPHA_NUM + " .,;-_?@", // SAFE_CHARS_UA_COMMENT CHARS_ALPHA_NUM + ".-_", // SAFE_CHARS_FILENAME CHARS_ALPHA_NUM + "!*'();:@&=+$,/?#[]-_.~%", // SAFE_CHARS_URI + CHARS_ALPHA_NUM + " .-_" // SAFE_CHARS_CSV }; std::string SanitizeString(const std::string& str, int rule) diff --git a/src/util/strencodings.h b/src/util/strencodings.h index 1671bd1f9a..1e8834d8e5 100644 --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -28,6 +28,7 @@ enum SafeChars SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset SAFE_CHARS_FILENAME, //!< Chars allowed in filenames SAFE_CHARS_URI, //!< Chars allowed in URIs (RFC 3986) + SAFE_CHARS_CSV //!< Chars allowed in fields stored as comma separated values }; /**