1
0
mirror of synced 2024-09-24 11:38:26 +02:00

Added auto loading patterns based on MIME types

This commit is contained in:
WerWolv 2020-11-21 14:39:16 +01:00
parent fb85f272a1
commit 4cd18b8358
5 changed files with 126 additions and 43 deletions

View File

@ -16,4 +16,10 @@ using s64 = std::int64_t;
using s128 = __int128_t;
#include "lang/result.hpp"
#include "lang/results.hpp"
#include "lang/results.hpp"
#if defined(__EMX__) || defined (WIN32)
#define MAGIC_PATH_SEPARATOR ";"
#else
#define MAGIC_PATH_SEPARATOR ":"
#endif

View File

@ -9,7 +9,7 @@
#include <concepts>
#include <cstring>
#include <filesystem>
#include "ImGuiFileBrowser.h"
#include "TextEditor.h"
@ -27,11 +27,13 @@ namespace hex {
private:
std::vector<lang::PatternData*> &m_patternData;
prv::Provider* &m_dataProvider;
std::filesystem::path m_possiblePatternFile;
bool m_windowOpen = true;
TextEditor m_textEditor;
imgui_addons::ImGuiFileBrowser m_fileBrowser;
void loadPatternFile(std::string path);
void clearPatternData();
void parsePattern(char *buffer);
};

View File

@ -21,7 +21,6 @@ int main() {
// Shared Data
std::vector<hex::lang::PatternData*> patternData;
hex::prv::Provider *dataProvider = nullptr;
// Create views
window.addView<hex::ViewHexEditor>(dataProvider, patternData);
window.addView<hex::ViewPattern>(dataProvider, patternData);

View File

@ -12,16 +12,10 @@
#include <magic.h>
#if defined(__EMX__) || defined (WIN32)
#define MAGIC_PATH_SEPARATOR ";"
#else
#define MAGIC_PATH_SEPARATOR ":"
#endif
namespace hex {
ViewInformation::ViewInformation(prv::Provider* &dataProvider) : View(), m_dataProvider(dataProvider) {
ViewInformation::ViewInformation(prv::Provider* &dataProvider)
: View(), m_dataProvider(dataProvider) {
View::subscribeEvent(Events::DataChanged, [this](const void*) {
this->m_shouldInvalidate = true;
});
@ -76,7 +70,7 @@ namespace hex {
}
{
std::vector<u8> buffer(this->m_dataProvider->getSize(), 0x00);
std::vector<u8> buffer(std::min(this->m_dataProvider->getSize(), size_t(0xFF'FFFF)), 0x00);
this->m_dataProvider->read(0x00, buffer.data(), buffer.size());
this->m_fileDescription.clear();
@ -95,12 +89,10 @@ namespace hex {
{
magic_t cookie = magic_open(MAGIC_NONE);
if (magic_load(cookie, magicFiles.c_str()) == -1)
goto skip_description;
this->m_fileDescription = magic_buffer(cookie, buffer.data(), buffer.size());
skip_description:
if (magic_load(cookie, magicFiles.c_str()) != -1)
this->m_fileDescription = magic_buffer(cookie, buffer.data(), buffer.size());
else
this->m_fileDescription = "";
magic_close(cookie);
}
@ -108,12 +100,10 @@ namespace hex {
{
magic_t cookie = magic_open(MAGIC_MIME);
if (magic_load(cookie, magicFiles.c_str()) == -1)
goto skip_mime;
this->m_mimeType = magic_buffer(cookie, buffer.data(), buffer.size());
skip_mime:
if (magic_load(cookie, magicFiles.c_str()) != -1)
this->m_mimeType = magic_buffer(cookie, buffer.data(), buffer.size());
else
this->m_mimeType = "";
magic_close(cookie);
}

View File

@ -7,6 +7,8 @@
#include "lang/evaluator.hpp"
#include "utils.hpp"
#include <magic.h>
namespace hex {
static const TextEditor::LanguageDefinition& PatternLanguage() {
@ -71,6 +73,66 @@ namespace hex {
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
this->m_textEditor.SetShowWhitespaces(false);
View::subscribeEvent(Events::DataChanged, [this](const void* userData) {
lang::Preprocessor preprocessor;
std::string magicFiles;
std::error_code error;
for (const auto &entry : std::filesystem::directory_iterator("magic", error)) {
if (entry.is_regular_file() && entry.path().extension() == ".mgc")
magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR;
}
std::vector<u8> buffer(this->m_dataProvider->getSize(), 0x00);
this->m_dataProvider->read(0, buffer.data(), buffer.size());
std::string mimeType;
magic_t cookie = magic_open(MAGIC_MIME_TYPE);
if (magic_load(cookie, magicFiles.c_str()) != -1)
mimeType = magic_buffer(cookie, buffer.data(), buffer.size());
magic_close(cookie);
bool foundCorrectType = false;
preprocessor.addPragmaHandler("MIME", [&mimeType, &foundCorrectType](std::string value) {
if (value == mimeType) {
foundCorrectType = true;
return true;
}
return !std::all_of(value.begin(), value.end(), isspace) && !value.ends_with('\n') && !value.ends_with('\r');
});
preprocessor.addDefaultPragramHandlers();
for (auto &entry : std::filesystem::directory_iterator("patterns")) {
if (!entry.is_regular_file())
continue;
FILE *file = fopen(entry.path().string().c_str(), "r");
if (file == nullptr)
continue;
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
rewind(file);
std::vector<char> buffer( size + 1, 0x00);
fread(buffer.data(), 1, size, file);
fclose(file);
preprocessor.preprocess(buffer.data());
if (foundCorrectType) {
this->m_possiblePatternFile = entry.path();
ImGui::OpenPopup("Accept Pattern");
ImGui::SetNextWindowSize(ImVec2(200, 100));
}
}
});
}
ViewPattern::~ViewPattern() {
@ -107,32 +169,54 @@ namespace hex {
ImGui::End();
if (this->m_fileBrowser.showFileDialog("Open Hex Pattern", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN, ImVec2(0, 0), ".hexpat")) {
this->loadPatternFile(this->m_fileBrowser.selected_path);
}
FILE *file = fopen(this->m_fileBrowser.selected_path.c_str(), "rb");
if (ImGui::BeginPopupModal("Accept Pattern", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove)) {
ImGui::TextUnformatted("A pattern compatible with this data type has been found:");
ImGui::Text("%ls", this->m_possiblePatternFile.filename().c_str());
ImGui::NewLine();
ImGui::Text("Do you want to load it?");
ImGui::NewLine();
if (file != nullptr) {
char *buffer;
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
rewind(file);
buffer = new char[size + 1];
fread(buffer, size, 1, file);
buffer[size] = 0x00;
fclose(file);
this->parsePattern(buffer);
this->m_textEditor.SetText(buffer);
delete[] buffer;
if (ImGui::Button("Yes", ImVec2(40, 20))) {
this->loadPatternFile(this->m_possiblePatternFile.string());
ImGui::CloseCurrentPopup();
}
ImGui::SameLine();
if (ImGui::Button("No", ImVec2(40, 20))) {
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
}
void ViewPattern::loadPatternFile(std::string path) {
FILE *file = fopen(path.c_str(), "rb");
if (file != nullptr) {
char *buffer;
fseek(file, 0, SEEK_END);
size_t size = ftell(file);
rewind(file);
buffer = new char[size + 1];
fread(buffer, size, 1, file);
buffer[size] = 0x00;
fclose(file);
this->parsePattern(buffer);
this->m_textEditor.SetText(buffer);
delete[] buffer;
}
}
void ViewPattern::clearPatternData() {
for (auto &data : this->m_patternData)
delete data;
@ -162,6 +246,8 @@ namespace hex {
this->clearPatternData();
this->postEvent(Events::PatternChanged);
preprocessor.addDefaultPragramHandlers();
auto [preprocessingResult, preprocesedCode] = preprocessor.preprocess(buffer);
if (preprocessingResult.failed())
return;