diff --git a/lib/libimhex/include/hex/helpers/magic.hpp b/lib/libimhex/include/hex/helpers/magic.hpp index 97c867f18..de6c3c8bc 100644 --- a/lib/libimhex/include/hex/helpers/magic.hpp +++ b/lib/libimhex/include/hex/helpers/magic.hpp @@ -16,10 +16,14 @@ namespace hex::magic { using namespace hex::literals; bool compile(); - std::string getDescription(const std::vector &data); - std::string getDescription(prv::Provider *provider, size_t size = 100_KiB); - std::string getMIMEType(const std::vector &data); - std::string getMIMEType(prv::Provider *provider, size_t size = 100_KiB); + std::string getDescription(const std::vector &data, bool firstEntryOnly = false); + std::string getDescription(prv::Provider *provider, size_t size = 100_KiB, bool firstEntryOnly = false); + std::string getMIMEType(const std::vector &data, bool firstEntryOnly = false); + std::string getMIMEType(prv::Provider *provider, size_t size = 100_KiB, bool firstEntryOnly = false); + std::string getExtensions(const std::vector &data, bool firstEntryOnly = false); + std::string getExtensions(prv::Provider *provider, size_t size = 100_KiB, bool firstEntryOnly = false); + std::string getAppleCreatorType(const std::vector &data, bool firstEntryOnly = false); + std::string getAppleCreatorType(prv::Provider *provider, size_t size = 100_KiB, bool firstEntryOnly = false); bool isValidMIMEType(const std::string &mimeType); diff --git a/lib/libimhex/source/helpers/magic.cpp b/lib/libimhex/source/helpers/magic.cpp index e2da124ad..6a5ac8154 100644 --- a/lib/libimhex/source/helpers/magic.cpp +++ b/lib/libimhex/source/helpers/magic.cpp @@ -95,50 +95,96 @@ namespace hex::magic { return result; } - std::string getDescription(const std::vector &data) { + std::string getDescription(const std::vector &data, bool firstEntryOnly) { auto magicFiles = getMagicFiles(); if (magicFiles.has_value()) { - magic_t ctx = magic_open(MAGIC_NONE); + magic_t ctx = magic_open(MAGIC_COMPRESS | (firstEntryOnly ? MAGIC_NONE : MAGIC_CONTINUE)); ON_SCOPE_EXIT { magic_close(ctx); }; if (magic_load(ctx, magicFiles->c_str()) == 0) { if (auto result = magic_buffer(ctx, data.data(), data.size()); result != nullptr) - return result; + return wolv::util::replaceStrings(result, "\\012-", "\n-"); } } return ""; } - std::string getDescription(prv::Provider *provider, size_t size) { + std::string getDescription(prv::Provider *provider, size_t size, bool firstEntryOnly) { std::vector buffer(std::min(provider->getSize(), size), 0x00); provider->read(provider->getBaseAddress(), buffer.data(), buffer.size()); - return getDescription(buffer); + return getDescription(buffer, firstEntryOnly); } - std::string getMIMEType(const std::vector &data) { + std::string getMIMEType(const std::vector &data, bool firstEntryOnly) { auto magicFiles = getMagicFiles(); if (magicFiles.has_value()) { - magic_t ctx = magic_open(MAGIC_MIME_TYPE); + magic_t ctx = magic_open(MAGIC_COMPRESS | MAGIC_MIME_TYPE | (firstEntryOnly ? MAGIC_NONE : MAGIC_CONTINUE)); ON_SCOPE_EXIT { magic_close(ctx); }; if (magic_load(ctx, magicFiles->c_str()) == 0) { if (auto result = magic_buffer(ctx, data.data(), data.size()); result != nullptr) - return result; + return wolv::util::replaceStrings(result, "\\012-", "\n-"); } } return ""; } - std::string getMIMEType(prv::Provider *provider, size_t size) { + std::string getExtensions(prv::Provider *provider, size_t size, bool firstEntryOnly) { std::vector buffer(std::min(provider->getSize(), size), 0x00); provider->read(provider->getBaseAddress(), buffer.data(), buffer.size()); - return getMIMEType(buffer); + return getExtensions(buffer, firstEntryOnly); + } + + std::string getExtensions(const std::vector &data, bool firstEntryOnly) { + auto magicFiles = getMagicFiles(); + + if (magicFiles.has_value()) { + magic_t ctx = magic_open(MAGIC_EXTENSION | (firstEntryOnly ? MAGIC_NONE : MAGIC_CONTINUE)); + ON_SCOPE_EXIT { magic_close(ctx); }; + + if (magic_load(ctx, magicFiles->c_str()) == 0) { + if (auto result = magic_buffer(ctx, data.data(), data.size()); result != nullptr) + return wolv::util::replaceStrings(result, "\\012-", "\n-"); + } + } + + return ""; + } + + std::string getAppleCreatorType(prv::Provider *provider, size_t size, bool firstEntryOnly) { + std::vector buffer(std::min(provider->getSize(), size), 0x00); + provider->read(provider->getBaseAddress(), buffer.data(), buffer.size()); + + return getAppleCreatorType(buffer, firstEntryOnly); + } + + std::string getAppleCreatorType(const std::vector &data, bool firstEntryOnly) { + auto magicFiles = getMagicFiles(); + + if (magicFiles.has_value()) { + magic_t ctx = magic_open(MAGIC_APPLE | (firstEntryOnly ? MAGIC_NONE : MAGIC_CONTINUE)); + ON_SCOPE_EXIT { magic_close(ctx); }; + + if (magic_load(ctx, magicFiles->c_str()) == 0) { + if (auto result = magic_buffer(ctx, data.data(), data.size()); result != nullptr) + return wolv::util::replaceStrings(result, "\\012-", "\n-"); + } + } + + return {}; + } + + std::string getMIMEType(prv::Provider *provider, size_t size, bool firstEntryOnly) { + std::vector buffer(std::min(provider->getSize(), size), 0x00); + provider->read(provider->getBaseAddress(), buffer.data(), buffer.size()); + + return getMIMEType(buffer, firstEntryOnly); } bool isValidMIMEType(const std::string &mimeType) { diff --git a/plugins/builtin/include/content/views/view_information.hpp b/plugins/builtin/include/content/views/view_information.hpp index 155a501a7..ccb4a436f 100644 --- a/plugins/builtin/include/content/views/view_information.hpp +++ b/plugins/builtin/include/content/views/view_information.hpp @@ -37,6 +37,8 @@ namespace hex::plugin::builtin { std::string m_dataDescription; std::string m_dataMimeType; + std::string m_dataAppleCreatorType; + std::string m_dataExtensions; DiagramDigram m_digram; DiagramLayeredDistribution m_layeredDistribution; diff --git a/plugins/builtin/romfs/lang/de_DE.json b/plugins/builtin/romfs/lang/de_DE.json index e469c9c7f..dd38b338d 100644 --- a/plugins/builtin/romfs/lang/de_DE.json +++ b/plugins/builtin/romfs/lang/de_DE.json @@ -673,7 +673,7 @@ "hex.builtin.view.information.block_size.desc": "{0} Blöcke mit {1} Bytes", "hex.builtin.view.information.byte_types": "Byte Typen", "hex.builtin.view.information.control": "Einstellungen", - "hex.builtin.view.information.description": "Beschreibung:", + "hex.builtin.view.information.description": "Beschreibung", "hex.builtin.view.information.digram": "Diagramm", "hex.builtin.view.information.distribution": "Byte Verteilung", "hex.builtin.view.information.encrypted": "Diese Daten sind vermutlich verschlüsselt oder komprimiert!", @@ -685,7 +685,7 @@ "hex.builtin.view.information.layered_distribution": "Schichtverteilung", "hex.builtin.view.information.magic": "Magic Informationen", "hex.builtin.view.information.magic_db_added": "Magic Datenbank hinzugefügt!", - "hex.builtin.view.information.mime": "MIME Typ:", + "hex.builtin.view.information.mime": "MIME Typ", "hex.builtin.view.information.name": "Dateninformationen", "hex.builtin.view.information.octet_stream_text": "", "hex.builtin.view.information.octet_stream_warning": "", diff --git a/plugins/builtin/romfs/lang/en_US.json b/plugins/builtin/romfs/lang/en_US.json index 5948a1451..2695277df 100644 --- a/plugins/builtin/romfs/lang/en_US.json +++ b/plugins/builtin/romfs/lang/en_US.json @@ -809,15 +809,17 @@ "hex.builtin.view.highlight_rules.menu.edit.rules": "Modify highlight rules...", "hex.builtin.view.information.analyze": "Analyze page", "hex.builtin.view.information.analyzing": "Analyzing...", + "hex.builtin.view.information.apple_type": "Apple Creator / Type Code", "hex.builtin.view.information.block_size": "Block size", "hex.builtin.view.information.block_size.desc": "{0} blocks of {1} bytes", "hex.builtin.view.information.byte_types": "Byte types", "hex.builtin.view.information.control": "Control", - "hex.builtin.view.information.description": "Description:", + "hex.builtin.view.information.description": "Description", "hex.builtin.view.information.digram": "Digram", "hex.builtin.view.information.distribution": "Byte distribution", "hex.builtin.view.information.encrypted": "This data is most likely encrypted or compressed!", "hex.builtin.view.information.entropy": "Entropy", + "hex.builtin.view.information.extension": "File Extension", "hex.builtin.view.information.file_entropy": "Overall entropy", "hex.builtin.view.information.highest_entropy": "Highest block entropy", "hex.builtin.view.information.lowest_entropy": "Lowest block entropy", @@ -825,7 +827,7 @@ "hex.builtin.view.information.layered_distribution": "Layered distribution", "hex.builtin.view.information.magic": "Magic information", "hex.builtin.view.information.magic_db_added": "Magic database added!", - "hex.builtin.view.information.mime": "MIME Type:", + "hex.builtin.view.information.mime": "MIME Type", "hex.builtin.view.information.name": "Data Information", "hex.builtin.view.information.octet_stream_text": "Unknown", "hex.builtin.view.information.octet_stream_warning": "application/octet-stream denotes an unknown data type.\n\nThis means that this data has no MIME type associated with it because it's not in a known format.", diff --git a/plugins/builtin/romfs/lang/es_ES.json b/plugins/builtin/romfs/lang/es_ES.json index 9fdf9ffa5..c62b5fb8c 100644 --- a/plugins/builtin/romfs/lang/es_ES.json +++ b/plugins/builtin/romfs/lang/es_ES.json @@ -671,7 +671,7 @@ "hex.builtin.view.information.block_size.desc": "{0} bloques de {1} bytes", "hex.builtin.view.information.byte_types": "Tipos de byte", "hex.builtin.view.information.control": "Ajustes", - "hex.builtin.view.information.description": "Descripción:", + "hex.builtin.view.information.description": "Descripción", "hex.builtin.view.information.digram": "Digrama", "hex.builtin.view.information.distribution": "Distribución de bytes", "hex.builtin.view.information.encrypted": "¡Estos datos están probablemente encriptados o comprimidos!", @@ -683,7 +683,7 @@ "hex.builtin.view.information.layered_distribution": "Distribución en capas", "hex.builtin.view.information.magic": "Información del 'magic'", "hex.builtin.view.information.magic_db_added": "¡Añadida base de datos de 'magic's!", - "hex.builtin.view.information.mime": "Tipo MIME:", + "hex.builtin.view.information.mime": "Tipo MIME", "hex.builtin.view.information.name": "Información de Datos:", "hex.builtin.view.information.octet_stream_text": "", "hex.builtin.view.information.octet_stream_warning": "", diff --git a/plugins/builtin/romfs/lang/it_IT.json b/plugins/builtin/romfs/lang/it_IT.json index bf7ea13df..12789be4c 100644 --- a/plugins/builtin/romfs/lang/it_IT.json +++ b/plugins/builtin/romfs/lang/it_IT.json @@ -671,7 +671,7 @@ "hex.builtin.view.information.block_size.desc": "{0} blocchi di {1} bytes", "hex.builtin.view.information.byte_types": "", "hex.builtin.view.information.control": "Controllo", - "hex.builtin.view.information.description": "Descrizione:", + "hex.builtin.view.information.description": "Descrizione", "hex.builtin.view.information.digram": "", "hex.builtin.view.information.distribution": "Distribuzione dei Byte", "hex.builtin.view.information.encrypted": "Questi dati sono probabilmente codificati o compressi!", @@ -683,7 +683,7 @@ "hex.builtin.view.information.layered_distribution": "", "hex.builtin.view.information.magic": "Informazione Magica", "hex.builtin.view.information.magic_db_added": "Database magico aggiunto!", - "hex.builtin.view.information.mime": "Tipo di MIME:", + "hex.builtin.view.information.mime": "Tipo di MIME", "hex.builtin.view.information.name": "Informazione sui Dati", "hex.builtin.view.information.octet_stream_text": "", "hex.builtin.view.information.octet_stream_warning": "", diff --git a/plugins/builtin/romfs/lang/ja_JP.json b/plugins/builtin/romfs/lang/ja_JP.json index 8d4b41876..718000aa9 100644 --- a/plugins/builtin/romfs/lang/ja_JP.json +++ b/plugins/builtin/romfs/lang/ja_JP.json @@ -671,7 +671,7 @@ "hex.builtin.view.information.block_size.desc": "{0} ブロック/ {1} バイト", "hex.builtin.view.information.byte_types": "", "hex.builtin.view.information.control": "コントロール", - "hex.builtin.view.information.description": "詳細:", + "hex.builtin.view.information.description": "詳細", "hex.builtin.view.information.digram": "", "hex.builtin.view.information.distribution": "バイト分布", "hex.builtin.view.information.encrypted": "暗号化や圧縮を経たデータと推測されます。", @@ -683,7 +683,7 @@ "hex.builtin.view.information.layered_distribution": "", "hex.builtin.view.information.magic": "Magic情報", "hex.builtin.view.information.magic_db_added": "Magicデータベースが追加されました。", - "hex.builtin.view.information.mime": "MIMEタイプ:", + "hex.builtin.view.information.mime": "MIMEタイプ", "hex.builtin.view.information.name": "データ解析", "hex.builtin.view.information.octet_stream_text": "", "hex.builtin.view.information.octet_stream_warning": "", diff --git a/plugins/builtin/romfs/lang/ko_KR.json b/plugins/builtin/romfs/lang/ko_KR.json index dbd375506..35e6ee1a2 100644 --- a/plugins/builtin/romfs/lang/ko_KR.json +++ b/plugins/builtin/romfs/lang/ko_KR.json @@ -692,7 +692,7 @@ "hex.builtin.view.information.block_size.desc": "{1}바이트 중 {0}블록", "hex.builtin.view.information.byte_types": "바이트 유형", "hex.builtin.view.information.control": "제어", - "hex.builtin.view.information.description": "설명:", + "hex.builtin.view.information.description": "설명", "hex.builtin.view.information.digram": "다이어그램", "hex.builtin.view.information.distribution": "바이트 분포", "hex.builtin.view.information.encrypted": "이 데이터는 암호화 또는 압축되어 있을 가능성이 높습니다!", @@ -704,7 +704,7 @@ "hex.builtin.view.information.layered_distribution": "계층화 분포", "hex.builtin.view.information.magic": "Magic 정보", "hex.builtin.view.information.magic_db_added": "Magic 데이터베이스 추가됨!", - "hex.builtin.view.information.mime": "MIME 유형:", + "hex.builtin.view.information.mime": "MIME 유형", "hex.builtin.view.information.name": "데이터 정보", "hex.builtin.view.information.octet_stream_text": "알 수 없음", "hex.builtin.view.information.octet_stream_warning": "application/octet-stream은 알 수 없는 데이터 유형을 나타냅니다.\n\n즉, 이 데이터는 알려진 형식이 아니기 때문에 연결된 MIME 유형이 없습니다.", diff --git a/plugins/builtin/romfs/lang/pt_BR.json b/plugins/builtin/romfs/lang/pt_BR.json index ae095b5b2..6b52d1b48 100644 --- a/plugins/builtin/romfs/lang/pt_BR.json +++ b/plugins/builtin/romfs/lang/pt_BR.json @@ -671,7 +671,7 @@ "hex.builtin.view.information.block_size.desc": "{0} blocks of {1} bytes", "hex.builtin.view.information.byte_types": "", "hex.builtin.view.information.control": "Controle", - "hex.builtin.view.information.description": "Descrição:", + "hex.builtin.view.information.description": "Descrição", "hex.builtin.view.information.digram": "", "hex.builtin.view.information.distribution": "Byte distribution", "hex.builtin.view.information.encrypted": "Esses dados provavelmente estão criptografados ou compactados!", @@ -683,7 +683,7 @@ "hex.builtin.view.information.layered_distribution": "", "hex.builtin.view.information.magic": "Informação Mágica", "hex.builtin.view.information.magic_db_added": "Magic database added!", - "hex.builtin.view.information.mime": "MIME Type:", + "hex.builtin.view.information.mime": "MIME Type", "hex.builtin.view.information.name": "Data Information", "hex.builtin.view.information.octet_stream_text": "", "hex.builtin.view.information.octet_stream_warning": "", diff --git a/plugins/builtin/romfs/lang/zh_CN.json b/plugins/builtin/romfs/lang/zh_CN.json index 7b30d49c9..692cf8957 100644 --- a/plugins/builtin/romfs/lang/zh_CN.json +++ b/plugins/builtin/romfs/lang/zh_CN.json @@ -685,7 +685,7 @@ "hex.builtin.view.information.block_size.desc": "{0} 块 × {1} 字节", "hex.builtin.view.information.byte_types": "字节类型", "hex.builtin.view.information.control": "控制", - "hex.builtin.view.information.description": "描述:", + "hex.builtin.view.information.description": "描述", "hex.builtin.view.information.digram": "图", "hex.builtin.view.information.distribution": "字节分布", "hex.builtin.view.information.encrypted": "此数据似乎经过了加密或压缩!", @@ -697,7 +697,7 @@ "hex.builtin.view.information.layered_distribution": "分层分布", "hex.builtin.view.information.magic": "LibMagic 信息", "hex.builtin.view.information.magic_db_added": "LibMagic 数据库已添加!", - "hex.builtin.view.information.mime": "MIME 类型:", + "hex.builtin.view.information.mime": "MIME 类型", "hex.builtin.view.information.name": "数据信息", "hex.builtin.view.information.octet_stream_text": "未知", "hex.builtin.view.information.octet_stream_warning": "application/octet-stream 表示未知的数据类型。\n\n这意味着该数据没有与之关联的 MIME 类型,因为它不是已知的格式。", diff --git a/plugins/builtin/romfs/lang/zh_TW.json b/plugins/builtin/romfs/lang/zh_TW.json index 821ea5075..7c56ae2b9 100644 --- a/plugins/builtin/romfs/lang/zh_TW.json +++ b/plugins/builtin/romfs/lang/zh_TW.json @@ -685,7 +685,7 @@ "hex.builtin.view.information.block_size.desc": "{0} blocks of {1} bytes", "hex.builtin.view.information.byte_types": "", "hex.builtin.view.information.control": "控制", - "hex.builtin.view.information.description": "說明:", + "hex.builtin.view.information.description": "說明", "hex.builtin.view.information.digram": "", "hex.builtin.view.information.distribution": "位元組分佈", "hex.builtin.view.information.encrypted": "此資料很有可能經過加密或壓縮!", @@ -697,7 +697,7 @@ "hex.builtin.view.information.layered_distribution": "", "hex.builtin.view.information.magic": "Magic information", "hex.builtin.view.information.magic_db_added": "Magic database added!", - "hex.builtin.view.information.mime": "MIME 類型:", + "hex.builtin.view.information.mime": "MIME 類型", "hex.builtin.view.information.name": "資料資訊", "hex.builtin.view.information.octet_stream_text": "未知", "hex.builtin.view.information.octet_stream_warning": "application/octet-stream denotes an unknown data type.\n\nThis means that this data has no MIME type associated with it because it's not in a known format.", diff --git a/plugins/builtin/source/content/views/view_information.cpp b/plugins/builtin/source/content/views/view_information.cpp index 2956a6659..943d00b95 100644 --- a/plugins/builtin/source/content/views/view_information.cpp +++ b/plugins/builtin/source/content/views/view_information.cpp @@ -29,6 +29,8 @@ namespace hex::plugin::builtin { m_blockSize = 0; m_dataMimeType.clear(); m_dataDescription.clear(); + m_dataAppleCreatorType.clear(); + m_dataExtensions.clear(); m_analyzedRegion = { 0, 0 }; }); @@ -87,8 +89,10 @@ namespace hex::plugin::builtin { { magic::compile(); - m_dataDescription = magic::getDescription(provider); - m_dataMimeType = magic::getMIMEType(provider); + m_dataDescription = magic::getDescription(provider); + m_dataMimeType = magic::getMIMEType(provider); + m_dataAppleCreatorType = magic::getAppleCreatorType(provider); + m_dataExtensions = magic::getExtensions(provider); } { @@ -228,8 +232,8 @@ namespace hex::plugin::builtin { ImGui::TextUnformatted("hex.builtin.view.information.mime"_lang); ImGui::TableNextColumn(); - if (m_dataMimeType == "application/octet-stream") { - ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, m_dataMimeType); + if (m_dataMimeType.contains("application/octet-stream")) { + ImGuiExt::TextFormatted("{}", m_dataMimeType); ImGui::SameLine(); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); ImGuiExt::HelpHover("hex.builtin.view.information.octet_stream_warning"_lang); @@ -239,6 +243,20 @@ namespace hex::plugin::builtin { } } + if (!m_dataAppleCreatorType.empty()) { + ImGui::TableNextColumn(); + ImGui::TextUnformatted("hex.builtin.view.information.apple_type"_lang); + ImGui::TableNextColumn(); + ImGuiExt::TextFormatted("{}", m_dataAppleCreatorType); + } + + if (!m_dataExtensions.empty()) { + ImGui::TableNextColumn(); + ImGui::TextUnformatted("hex.builtin.view.information.extension"_lang); + ImGui::TableNextColumn(); + ImGuiExt::TextFormatted("{}", m_dataExtensions); + } + ImGui::EndTable(); } diff --git a/plugins/builtin/source/content/views/view_pattern_editor.cpp b/plugins/builtin/source/content/views/view_pattern_editor.cpp index 859cbc786..c5d7330d3 100644 --- a/plugins/builtin/source/content/views/view_pattern_editor.cpp +++ b/plugins/builtin/source/content/views/view_pattern_editor.cpp @@ -854,7 +854,7 @@ namespace hex::plugin::builtin { pl::PatternLanguage runtime; ContentRegistry::PatternLanguage::configureRuntime(runtime, provider); - auto mimeType = magic::getMIMEType(provider); + auto mimeType = magic::getMIMEType(provider, true); bool foundCorrectType = false; runtime.addPragma("MIME", [&mimeType, &foundCorrectType](const pl::PatternLanguage &runtime, const std::string &value) {