MemoryWidget: Simplify the search logic

Fix leading nul bytes being ignored in hex search
This commit is contained in:
Sepalani 2021-09-01 14:53:20 +04:00
parent 6129290d31
commit 94cba46467
2 changed files with 44 additions and 80 deletions

View File

@ -13,6 +13,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QPushButton> #include <QPushButton>
#include <QRadioButton> #include <QRadioButton>
#include <QRegularExpression>
#include <QScrollArea> #include <QScrollArea>
#include <QSpacerItem> #include <QSpacerItem>
#include <QSplitter> #include <QSplitter>
@ -116,7 +117,7 @@ void MemoryWidget::CreateWidgets()
m_find_next = new QPushButton(tr("Find &Next")); m_find_next = new QPushButton(tr("Find &Next"));
m_find_previous = new QPushButton(tr("Find &Previous")); m_find_previous = new QPushButton(tr("Find &Previous"));
m_find_ascii = new QRadioButton(tr("ASCII")); 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; m_result_label = new QLabel;
search_layout->addWidget(m_find_next); search_layout->addWidget(m_find_next);
@ -479,17 +480,11 @@ void MemoryWidget::ValidateSearchValue()
QFont font; QFont font;
QPalette palette; 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); font.setBold(true);
palette.setColor(QPalette::Text, Qt::red); palette.setColor(QPalette::Text, Qt::red);
} }
}
m_data_edit->setFont(font); m_data_edit->setFont(font);
m_data_edit->setPalette(palette); m_data_edit->setPalette(palette);
@ -523,44 +518,17 @@ void MemoryWidget::OnSetValue()
return; return;
} }
AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_memory_view->GetAddressSpace()); if (!IsValueValid())
if (m_find_ascii->isChecked())
{
const QByteArray bytes = m_data_edit->text().toUtf8();
for (char c : bytes)
accessors->WriteU8(addr++, static_cast<u8>(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.")); ModalMessageBox::critical(this, tr("Error"), tr("Bad value provided."));
return; return;
} }
if (length <= 2) AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_memory_view->GetAddressSpace());
{
accessors->WriteU8(addr, static_cast<u8>(value)); const QByteArray bytes = GetValueData();
} for (const char c : bytes)
else if (length <= 4) accessors->WriteU8(addr++, static_cast<u8>(c));
{
accessors->WriteU16(addr, static_cast<u16>(value));
}
else if (length <= 8)
{
accessors->WriteU32(addr, static_cast<u32>(value));
}
else
accessors->WriteU64(addr, value);
}
Update(); Update();
} }
@ -616,46 +584,40 @@ void MemoryWidget::OnDumpFakeVMEM()
std::distance(accessors->begin(), accessors->end())); std::distance(accessors->begin(), accessors->end()));
} }
std::vector<u8> MemoryWidget::GetValueData() const bool MemoryWidget::IsValueValid() const
{ {
std::vector<u8> 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()) if (m_find_ascii->isChecked())
{ return value;
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);
if (!good) return QByteArray::fromHex(value);
return {};
int size;
if (value == static_cast<u8>(value))
size = sizeof(u8);
else if (value == static_cast<u16>(value))
size = sizeof(u16);
else if (value == static_cast<u32>(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;
} }
void MemoryWidget::FindValue(bool next) void MemoryWidget::FindValue(bool next)
{ {
std::vector<u8> 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")); m_result_label->setText(tr("No Value Given"));
return; return;
@ -671,8 +633,8 @@ void MemoryWidget::FindValue(bool next)
AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_memory_view->GetAddressSpace()); AddressSpace::Accessors* accessors = AddressSpace::GetAccessors(m_memory_view->GetAddressSpace());
auto found_addr = const auto found_addr = accessors->Search(addr, reinterpret_cast<const u8*>(search_for.data()),
accessors->Search(addr, search_for.data(), static_cast<u32>(search_for.size()), next); static_cast<u32>(search_for.size()), next);
if (found_addr.has_value()) if (found_addr.has_value())
{ {

View File

@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include <QByteArray>
#include <QDockWidget> #include <QDockWidget>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -56,7 +57,8 @@ private:
void OnDumpARAM(); void OnDumpARAM();
void OnDumpFakeVMEM(); void OnDumpFakeVMEM();
std::vector<u8> GetValueData() const; bool IsValueValid() const;
QByteArray GetValueData() const;
void FindValue(bool next); void FindValue(bool next);