diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 12f42cf21807b..12e2b1d6af1aa 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -872,6 +872,7 @@ "hex.builtin.view.hex_editor.menu.edit.paste.popup.button.selection": "Paste only over selection", "hex.builtin.view.hex_editor.menu.edit.paste_all": "Paste all", "hex.builtin.view.hex_editor.menu.edit.paste_all_string": "Paste all as string", + "hex.builtin.view.hex_editor.menu.edit.paste_all_decoded_base64_string": "Paste all as decoded base64 string", "hex.builtin.view.hex_editor.menu.edit.remove": "Remove...", "hex.builtin.view.hex_editor.menu.edit.resize": "Resize...", "hex.builtin.view.hex_editor.menu.edit.select_all": "Select all", diff --git a/plugins/builtin/romfs/lang/fr_FR.json b/plugins/builtin/romfs/lang/fr_FR.json index 4509327ab6d8a..1596e332aff32 100644 --- a/plugins/builtin/romfs/lang/fr_FR.json +++ b/plugins/builtin/romfs/lang/fr_FR.json @@ -834,6 +834,7 @@ "hex.builtin.view.hex_editor.menu.edit.paste.popup.button.selection": "Coller uniquement sur la sélection", "hex.builtin.view.hex_editor.menu.edit.paste_all": "Coller tout", "hex.builtin.view.hex_editor.menu.edit.paste_all_string": "Coller tout en tant que chaîne", + "hex.builtin.view.hex_editor.menu.edit.paste_all_decoded_base64_string":"Coller tout comme chaîne base64 décodée", "hex.builtin.view.hex_editor.menu.edit.remove": "Supprimer...", "hex.builtin.view.hex_editor.menu.edit.resize": "Redimensionner...", "hex.builtin.view.hex_editor.menu.edit.select_all": "Sélectionner tout", diff --git a/plugins/builtin/romfs/lang/pl_PL.json b/plugins/builtin/romfs/lang/pl_PL.json index a820ff30c0ba6..9a7a9276cdda0 100644 --- a/plugins/builtin/romfs/lang/pl_PL.json +++ b/plugins/builtin/romfs/lang/pl_PL.json @@ -836,6 +836,7 @@ "hex.builtin.view.hex_editor.menu.edit.paste.popup.button.selection": "Wklej tylko nad zaznaczeniem", "hex.builtin.view.hex_editor.menu.edit.paste_all": "Wklej wszystko", "hex.builtin.view.hex_editor.menu.edit.paste_all_string": "Wklej wszystko jako string", + "hex.builtin.view.hex_editor.menu.edit.paste_all_decoded_base64_string": "Wklej wszystko jako zdekodowany ciąg base64", "hex.builtin.view.hex_editor.menu.edit.remove": "Usuń...", "hex.builtin.view.hex_editor.menu.edit.resize": "Zmień rozmiar...", "hex.builtin.view.hex_editor.menu.edit.select_all": "Zaznacz wszystko", diff --git a/plugins/builtin/romfs/lang/uk_UA.json b/plugins/builtin/romfs/lang/uk_UA.json index 1829651887d77..374b64de179d7 100644 --- a/plugins/builtin/romfs/lang/uk_UA.json +++ b/plugins/builtin/romfs/lang/uk_UA.json @@ -825,6 +825,7 @@ "hex.builtin.view.hex_editor.menu.edit.paste.popup.button.selection": "Вставити тільки над виділеним фрагментом", "hex.builtin.view.hex_editor.menu.edit.paste_all": "Вставити все", "hex.builtin.view.hex_editor.menu.edit.paste_all_string": "Вставити все як рядок", + "hex.builtin.view.hex_editor.menu.edit.paste_all_decoded_base64_string": "Вставити все як декодований рядок base64", "hex.builtin.view.hex_editor.menu.edit.remove": "Видалити...", "hex.builtin.view.hex_editor.menu.edit.set_base": "Встановити початкову адресу...", "hex.builtin.view.hex_editor.menu.edit.set_page_size": "Встановити кількість рядків...", diff --git a/plugins/builtin/romfs/lang/zh_CN.json b/plugins/builtin/romfs/lang/zh_CN.json index ccc45c1c48cbb..d9bf9d0d87547 100644 --- a/plugins/builtin/romfs/lang/zh_CN.json +++ b/plugins/builtin/romfs/lang/zh_CN.json @@ -838,6 +838,7 @@ "hex.builtin.view.hex_editor.menu.edit.paste.popup.button.selection": "仅覆盖选区", "hex.builtin.view.hex_editor.menu.edit.paste_all": "粘贴全部", "hex.builtin.view.hex_editor.menu.edit.paste_all_string": "全部作为字符串粘贴", + "hex.builtin.view.hex_editor.menu.edit.paste_all_decoded_base64_string":"粘贴所有内容为解码后的Base64字符串", "hex.builtin.view.hex_editor.menu.edit.remove": "删除……", "hex.builtin.view.hex_editor.menu.edit.resize": "修改大小……", "hex.builtin.view.hex_editor.menu.edit.select_all": "全选", diff --git a/plugins/builtin/source/content/views/view_hex_editor.cpp b/plugins/builtin/source/content/views/view_hex_editor.cpp index a2f9deb027214..f587558682589 100644 --- a/plugins/builtin/source/content/views/view_hex_editor.cpp +++ b/plugins/builtin/source/content/views/view_hex_editor.cpp @@ -856,7 +856,53 @@ namespace hex::plugin::builtin { ImGui::SetClipboardText(result.c_str()); } - static void pasteBytes(const Region &selection, bool selectionCheck, bool asPlainText) { + bool isValidBase64(const std::string &input) { + if (input.empty() || input.size() % 4 != 0) + { + log::info("Empty base64 string or check the padding: {}", input ); + return false; + } + for (char c : input) { + if (!((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '+' || c == '/' || c == '=' || c == '\n' || c == '\r')) + { + log::info("Invalid Base64 string: {}", input); + return false; + } + } + return true; + } + + std::vector decodeBase64(const std::string &input) { + + if(!isValidBase64(input)){ + return {}; + } + + static constexpr char sDecodingTable[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + std::vector output; + int val = 0, valb = -8; + + for (char c : input) { + if (c == '=' || c == '\n' || c == '\r') + break; + + const char *p = std::strchr(sDecodingTable, c); + + if (!p) + continue; + + val = (val << 6) + (p - sDecodingTable); + valb += 6; + if (valb >= 0) { + output.push_back(u8((val >> valb) & 0xFF)); + valb -= 8; + } + } + + return output; + } + + static void pasteBytes(const Region &selection, bool selectionCheck, bool asPlainText, bool asBase64=false) { auto provider = ImHexApi::Provider::get(); if (provider == nullptr) return; @@ -866,7 +912,10 @@ namespace hex::plugin::builtin { return; std::vector buffer; - if (asPlainText) { + if(asBase64){ + buffer = decodeBase64(clipboard); + } + else if (asPlainText) { // Directly reinterpret clipboard as an array of bytes std::string cp = clipboard; buffer = std::vector(cp.begin(), cp.end()); @@ -1550,6 +1599,20 @@ namespace hex::plugin::builtin { ImHexApi::HexEditor::isSelectionValid, this); + /* Paste... > Paste all as decoded base64 string */ + ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.paste_as", "hex.builtin.view.hex_editor.menu.edit.paste_all_decoded_base64_string" }, ICON_VS_BLANK, 1520, + Shortcut::None, + [] { + pasteBytes( + ImHexApi::HexEditor::getSelection().value_or(ImHexApi::HexEditor::ProviderRegion(Region { 0, 0 }, ImHexApi::Provider::get())), + false, + false, + true + ); + }, + ImHexApi::HexEditor::isSelectionValid, + this); + /* Select */ ContentRegistry::UserInterface::addMenuItem({ "hex.builtin.menu.edit", "hex.builtin.view.hex_editor.menu.edit.select" }, ICON_VS_LIST_SELECTION, 1525, CTRLCMD + SHIFT + Keys::A,