From 4ee53701e61a24dc691d6a717875314cc5740840 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Fri, 17 Mar 2023 08:16:13 +0100 Subject: [PATCH] impr: Allow Regex find strategy specify string type and minimum length --- .../include/content/views/view_find.hpp | 22 +++-- .../source/content/views/view_find.cpp | 89 +++++++++++-------- 2 files changed, 68 insertions(+), 43 deletions(-) diff --git a/plugins/builtin/include/content/views/view_find.hpp b/plugins/builtin/include/content/views/view_find.hpp index 61731d9ba..e2ca92eae 100644 --- a/plugins/builtin/include/content/views/view_find.hpp +++ b/plugins/builtin/include/content/views/view_find.hpp @@ -43,18 +43,20 @@ namespace hex::plugin::builtin { Value } mode = Mode::Strings; + enum class StringType : int { ASCII = 0, UTF16LE = 1, UTF16BE = 2, ASCII_UTF16LE = 3, ASCII_UTF16BE = 4 }; + struct Strings { int minLength = 5; - enum class Type : int { ASCII = 0, UTF16LE = 1, UTF16BE = 2, ASCII_UTF16LE = 3, ASCII_UTF16BE = 4 } type = Type::ASCII; bool nullTermination = false; + StringType type = StringType::ASCII; - bool m_lowerCaseLetters = true; - bool m_upperCaseLetters = true; - bool m_numbers = true; - bool m_underscores = true; - bool m_symbols = true; - bool m_spaces = true; - bool m_lineFeeds = false; + bool lowerCaseLetters = true; + bool upperCaseLetters = true; + bool numbers = true; + bool underscores = true; + bool symbols = true; + bool spaces = true; + bool lineFeeds = false; } strings; struct Sequence { @@ -62,6 +64,10 @@ namespace hex::plugin::builtin { } bytes; struct Regex { + int minLength = 5; + bool nullTermination = false; + StringType type = StringType::ASCII; + std::string pattern; bool fullMatch = true; } regex; diff --git a/plugins/builtin/source/content/views/view_find.cpp b/plugins/builtin/source/content/views/view_find.cpp index b8174108d..af29bdb28 100644 --- a/plugins/builtin/source/content/views/view_find.cpp +++ b/plugins/builtin/source/content/views/view_find.cpp @@ -212,7 +212,7 @@ namespace hex::plugin::builtin { } std::vector ViewFind::searchStrings(Task &task, prv::Provider *provider, hex::Region searchRegion, const SearchSettings::Strings &settings) { - using enum SearchSettings::Strings::Type; + using enum SearchSettings::StringType; std::vector results; @@ -243,9 +243,9 @@ namespace hex::plugin::builtin { const auto [decodeType, endian] = [&] -> std::pair { if (settings.type == ASCII) return { Occurrence::DecodeType::ASCII, std::endian::native }; - else if (settings.type == SearchSettings::Strings::Type::UTF16BE) + else if (settings.type == SearchSettings::StringType::UTF16BE) return { Occurrence::DecodeType::UTF16, std::endian::big }; - else if (settings.type == SearchSettings::Strings::Type::UTF16LE) + else if (settings.type == SearchSettings::StringType::UTF16LE) return { Occurrence::DecodeType::UTF16, std::endian::little }; else return { Occurrence::DecodeType::Binary, std::endian::native }; @@ -256,13 +256,13 @@ namespace hex::plugin::builtin { u64 endAddress = reader.end().getAddress(); for (u8 byte : reader) { bool validChar = - (settings.m_lowerCaseLetters && std::islower(byte)) || - (settings.m_upperCaseLetters && std::isupper(byte)) || - (settings.m_numbers && std::isdigit(byte)) || - (settings.m_spaces && std::isspace(byte) && byte != '\r' && byte != '\n') || - (settings.m_underscores && byte == '_') || - (settings.m_symbols && std::ispunct(byte) && !std::isspace(byte)) || - (settings.m_lineFeeds && (byte == '\r' || byte == '\n')); + (settings.lowerCaseLetters && std::islower(byte)) || + (settings.upperCaseLetters && std::isupper(byte)) || + (settings.numbers && std::isdigit(byte)) || + (settings.spaces && std::isspace(byte) && byte != '\r' && byte != '\n') || + (settings.underscores && byte == '_') || + (settings.symbols && std::ispunct(byte) && !std::isspace(byte)) || + (settings.lineFeeds && (byte == '\r' || byte == '\n')); if (settings.type == UTF16LE) { // Check if second byte of UTF-16 encoded string is 0x00 @@ -321,15 +321,16 @@ namespace hex::plugin::builtin { std::vector ViewFind::searchRegex(Task &task, prv::Provider *provider, hex::Region searchRegion, const SearchSettings::Regex &settings) { auto stringOccurrences = searchStrings(task, provider, searchRegion, SearchSettings::Strings { - .minLength = 1, - .type = SearchSettings::Strings::Type::ASCII, - .m_lowerCaseLetters = true, - .m_upperCaseLetters = true, - .m_numbers = true, - .m_underscores = true, - .m_symbols = true, - .m_spaces = true, - .m_lineFeeds = true + .minLength = settings.minLength, + .nullTermination = settings.nullTermination, + .type = settings.type, + .lowerCaseLetters = true, + .upperCaseLetters = true, + .numbers = true, + .underscores = true, + .symbols = true, + .spaces = true, + .lineFeeds = true }); std::vector result; @@ -577,6 +578,14 @@ namespace hex::plugin::builtin { ImGui::NewLine(); if (ImGui::BeginTabBar("SearchMethods")) { + const std::array StringTypes = { + "hex.builtin.common.encoding.ascii"_lang, + "hex.builtin.common.encoding.utf16le"_lang, + "hex.builtin.common.encoding.utf16be"_lang, + hex::format("{} + {}", "hex.builtin.common.encoding.ascii"_lang, "hex.builtin.common.encoding.utf16le"_lang), + hex::format("{} + {}", "hex.builtin.common.encoding.ascii"_lang, "hex.builtin.common.encoding.utf16be"_lang) + }; + auto &mode = this->m_searchSettings.mode; if (ImGui::BeginTabItem("hex.builtin.view.find.strings"_lang)) { auto &settings = this->m_searchSettings.strings; @@ -586,17 +595,9 @@ namespace hex::plugin::builtin { if (settings.minLength < 1) settings.minLength = 1; - const std::array StringTypes = { - "hex.builtin.common.encoding.ascii"_lang, - "hex.builtin.common.encoding.utf16le"_lang, - "hex.builtin.common.encoding.utf16be"_lang, - hex::format("{} + {}", "hex.builtin.common.encoding.ascii"_lang, "hex.builtin.common.encoding.utf16le"_lang), - hex::format("{} + {}", "hex.builtin.common.encoding.ascii"_lang, "hex.builtin.common.encoding.utf16be"_lang) - }; - if (ImGui::BeginCombo("hex.builtin.common.type"_lang, StringTypes[std::to_underlying(settings.type)].c_str())) { for (size_t i = 0; i < StringTypes.size(); i++) { - auto type = static_cast(i); + auto type = static_cast(i); if (ImGui::Selectable(StringTypes[i].c_str(), type == settings.type)) settings.type = type; @@ -608,13 +609,13 @@ namespace hex::plugin::builtin { ImGui::Checkbox("hex.builtin.view.find.strings.null_term"_lang, &settings.nullTermination); ImGui::Header("hex.builtin.view.find.strings.chars"_lang); - ImGui::Checkbox(hex::format("{} [a-z]", "hex.builtin.view.find.strings.lower_case"_lang.get()).c_str(), &settings.m_lowerCaseLetters); - ImGui::Checkbox(hex::format("{} [A-Z]", "hex.builtin.view.find.strings.upper_case"_lang.get()).c_str(), &settings.m_upperCaseLetters); - ImGui::Checkbox(hex::format("{} [0-9]", "hex.builtin.view.find.strings.numbers"_lang.get()).c_str(), &settings.m_numbers); - ImGui::Checkbox(hex::format("{} [_]", "hex.builtin.view.find.strings.underscores"_lang.get()).c_str(), &settings.m_underscores); - ImGui::Checkbox(hex::format("{} [!\"#$%...]", "hex.builtin.view.find.strings.symbols"_lang.get()).c_str(), &settings.m_symbols); - ImGui::Checkbox(hex::format("{} [ \\f\\t\\v]", "hex.builtin.view.find.strings.spaces"_lang.get()).c_str(), &settings.m_spaces); - ImGui::Checkbox(hex::format("{} [\\r\\n]", "hex.builtin.view.find.strings.line_feeds"_lang.get()).c_str(), &settings.m_lineFeeds); + ImGui::Checkbox(hex::format("{} [a-z]", "hex.builtin.view.find.strings.lower_case"_lang.get()).c_str(), &settings.lowerCaseLetters); + ImGui::Checkbox(hex::format("{} [A-Z]", "hex.builtin.view.find.strings.upper_case"_lang.get()).c_str(), &settings.upperCaseLetters); + ImGui::Checkbox(hex::format("{} [0-9]", "hex.builtin.view.find.strings.numbers"_lang.get()).c_str(), &settings.numbers); + ImGui::Checkbox(hex::format("{} [_]", "hex.builtin.view.find.strings.underscores"_lang.get()).c_str(), &settings.underscores); + ImGui::Checkbox(hex::format("{} [!\"#$%...]", "hex.builtin.view.find.strings.symbols"_lang.get()).c_str(), &settings.symbols); + ImGui::Checkbox(hex::format("{} [ \\f\\t\\v]", "hex.builtin.view.find.strings.spaces"_lang.get()).c_str(), &settings.spaces); + ImGui::Checkbox(hex::format("{} [\\r\\n]", "hex.builtin.view.find.strings.line_feeds"_lang.get()).c_str(), &settings.lineFeeds); } this->m_settingsValid = true; @@ -637,6 +638,24 @@ namespace hex::plugin::builtin { mode = SearchSettings::Mode::Regex; + ImGui::InputInt("hex.builtin.view.find.strings.min_length"_lang, &settings.minLength, 1, 1); + if (settings.minLength < 1) + settings.minLength = 1; + + if (ImGui::BeginCombo("hex.builtin.common.type"_lang, StringTypes[std::to_underlying(settings.type)].c_str())) { + for (size_t i = 0; i < StringTypes.size(); i++) { + auto type = static_cast(i); + + if (ImGui::Selectable(StringTypes[i].c_str(), type == settings.type)) + settings.type = type; + } + ImGui::EndCombo(); + } + + ImGui::Checkbox("hex.builtin.view.find.strings.null_term"_lang, &settings.nullTermination); + + ImGui::NewLine(); + ImGui::InputTextIcon("hex.builtin.view.find.regex.pattern"_lang, ICON_VS_REGEX, settings.pattern); try {