From 94cba464675f748ae3df1296549aa5c486143fa5 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Wed, 1 Sep 2021 14:53:20 +0400 Subject: [PATCH] MemoryWidget: Simplify the search logic Fix leading nul bytes being ignored in hex search --- .../Core/DolphinQt/Debugger/MemoryWidget.cpp | 120 ++++++------------ Source/Core/DolphinQt/Debugger/MemoryWidget.h | 4 +- 2 files changed, 44 insertions(+), 80 deletions(-) diff --git a/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp b/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp index 5d065baf2f..fe1307ec41 100644 --- a/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp +++ b/Source/Core/DolphinQt/Debugger/MemoryWidget.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -116,7 +117,7 @@ void MemoryWidget::CreateWidgets() m_find_next = new QPushButton(tr("Find &Next")); m_find_previous = new QPushButton(tr("Find &Previous")); m_find_ascii = new QRadioButton(tr("ASCII")); - m_find_hex = new QRadioButton(tr("Hex")); + m_find_hex = new QRadioButton(tr("Hex string")); m_result_label = new QLabel; search_layout->addWidget(m_find_next); @@ -479,16 +480,10 @@ void MemoryWidget::ValidateSearchValue() QFont font; QPalette palette; - if (m_find_hex->isChecked() && !m_data_edit->text().isEmpty()) + if (!IsValueValid()) { - bool good; - m_data_edit->text().toULongLong(&good, 16); - - if (!good) - { - font.setBold(true); - palette.setColor(QPalette::Text, Qt::red); - } + font.setBold(true); + palette.setColor(QPalette::Text, Qt::red); } m_data_edit->setFont(font); @@ -523,44 +518,17 @@ void MemoryWidget::OnSetValue() return; } + if (!IsValueValid()) + { + ModalMessageBox::critical(this, tr("Error"), tr("Bad value provided.")); + return; + } + AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_memory_view->GetAddressSpace()); - if (m_find_ascii->isChecked()) - { - const QByteArray bytes = m_data_edit->text().toUtf8(); - - for (char c : bytes) - accessors->WriteU8(addr++, static_cast(c)); - } - else - { - bool good_value; - const QString text = m_data_edit->text(); - const int length = - text.startsWith(QStringLiteral("0x"), Qt::CaseInsensitive) ? text.size() - 2 : text.size(); - const u64 value = text.toULongLong(&good_value, 16); - - if (!good_value) - { - ModalMessageBox::critical(this, tr("Error"), tr("Bad value provided.")); - return; - } - - if (length <= 2) - { - accessors->WriteU8(addr, static_cast(value)); - } - else if (length <= 4) - { - accessors->WriteU16(addr, static_cast(value)); - } - else if (length <= 8) - { - accessors->WriteU32(addr, static_cast(value)); - } - else - accessors->WriteU64(addr, value); - } + const QByteArray bytes = GetValueData(); + for (const char c : bytes) + accessors->WriteU8(addr++, static_cast(c)); Update(); } @@ -616,46 +584,40 @@ void MemoryWidget::OnDumpFakeVMEM() std::distance(accessors->begin(), accessors->end())); } -std::vector MemoryWidget::GetValueData() const +bool MemoryWidget::IsValueValid() const { - std::vector search_for; // Series of bytes we want to look for + if (m_find_ascii->isChecked()) + return true; + const QRegularExpression is_hex(QStringLiteral("^([0-9A-F]{2})*$"), + QRegularExpression::CaseInsensitiveOption); + const QRegularExpressionMatch match = is_hex.match(m_data_edit->text()); + return match.hasMatch(); +} + +QByteArray MemoryWidget::GetValueData() const +{ + if (!IsValueValid()) + return QByteArray(); + + const QByteArray value = m_data_edit->text().toUtf8(); if (m_find_ascii->isChecked()) - { - const QByteArray bytes = m_data_edit->text().toUtf8(); - search_for.assign(bytes.begin(), bytes.end()); - } - else - { - bool good; - u64 value = m_data_edit->text().toULongLong(&good, 16); + return value; - if (!good) - return {}; - - int size; - - if (value == static_cast(value)) - size = sizeof(u8); - else if (value == static_cast(value)) - size = sizeof(u16); - else if (value == static_cast(value)) - size = sizeof(u32); - else - size = sizeof(u64); - - for (int i = size - 1; i >= 0; i--) - search_for.push_back((value >> (i * 8)) & 0xFF); - } - - return search_for; + return QByteArray::fromHex(value); } void MemoryWidget::FindValue(bool next) { - std::vector search_for = GetValueData(); + if (!IsValueValid()) + { + m_result_label->setText(tr("Bad value provided.")); + return; + } - if (search_for.empty()) + const QByteArray search_for = GetValueData(); + + if (search_for.isEmpty()) { m_result_label->setText(tr("No Value Given")); return; @@ -671,8 +633,8 @@ void MemoryWidget::FindValue(bool next) AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_memory_view->GetAddressSpace()); - auto found_addr = - accessors->Search(addr, search_for.data(), static_cast(search_for.size()), next); + const auto found_addr = accessors->Search(addr, reinterpret_cast(search_for.data()), + static_cast(search_for.size()), next); if (found_addr.has_value()) { diff --git a/Source/Core/DolphinQt/Debugger/MemoryWidget.h b/Source/Core/DolphinQt/Debugger/MemoryWidget.h index c0240c7085..2a96f9d2ec 100644 --- a/Source/Core/DolphinQt/Debugger/MemoryWidget.h +++ b/Source/Core/DolphinQt/Debugger/MemoryWidget.h @@ -5,6 +5,7 @@ #include +#include #include #include "Common/CommonTypes.h" @@ -56,7 +57,8 @@ private: void OnDumpARAM(); void OnDumpFakeVMEM(); - std::vector GetValueData() const; + bool IsValueValid() const; + QByteArray GetValueData() const; void FindValue(bool next);