fix: Potential crash when loading incorrect data processor node files
This commit is contained in:
parent
aac9bf3896
commit
52c517d38d
@ -1,4 +1,5 @@
|
|||||||
#include "content/views/view_data_processor.hpp"
|
#include "content/views/view_data_processor.hpp"
|
||||||
|
#include "content/popups/popup_notification.hpp"
|
||||||
|
|
||||||
#include <hex/api/content_registry.hpp>
|
#include <hex/api/content_registry.hpp>
|
||||||
|
|
||||||
@ -7,6 +8,7 @@
|
|||||||
#include <hex/providers/provider.hpp>
|
#include <hex/providers/provider.hpp>
|
||||||
#include <hex/api/project_file_manager.hpp>
|
#include <hex/api/project_file_manager.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <imnodes.h>
|
#include <imnodes.h>
|
||||||
#include <imnodes_internal.h>
|
#include <imnodes_internal.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
@ -358,7 +360,7 @@ namespace hex::plugin::builtin {
|
|||||||
ViewDataProcessor::processNodes(*this->m_workspaceStack->back());
|
ViewDataProcessor::processNodes(*this->m_workspaceStack->back());
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Import bookmarks */
|
/* Import Nodes */
|
||||||
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.data_processor" }, 4050, Shortcut::None, [this]{
|
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.data_processor" }, 4050, Shortcut::None, [this]{
|
||||||
fs::openFileBrowser(fs::DialogMode::Open, { {"hex.builtin.view.data_processor.name"_lang, "hexnode" } },
|
fs::openFileBrowser(fs::DialogMode::Open, { {"hex.builtin.view.data_processor.name"_lang, "hexnode" } },
|
||||||
[&](const std::fs::path &path) {
|
[&](const std::fs::path &path) {
|
||||||
@ -370,7 +372,7 @@ namespace hex::plugin::builtin {
|
|||||||
});
|
});
|
||||||
}, ImHexApi::Provider::isValid);
|
}, ImHexApi::Provider::isValid);
|
||||||
|
|
||||||
/* Export bookmarks */
|
/* Export Nodes */
|
||||||
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.data_processor" }, 8050, Shortcut::None, [this]{
|
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.export", "hex.builtin.menu.file.export.data_processor" }, 8050, Shortcut::None, [this]{
|
||||||
fs::openFileBrowser(fs::DialogMode::Save, { {"hex.builtin.view.data_processor.name"_lang, "hexnode" } },
|
fs::openFileBrowser(fs::DialogMode::Save, { {"hex.builtin.view.data_processor.name"_lang, "hexnode" } },
|
||||||
[&, this](const std::fs::path &path) {
|
[&, this](const std::fs::path &path) {
|
||||||
@ -940,87 +942,91 @@ namespace hex::plugin::builtin {
|
|||||||
workspace.endNodes.clear();
|
workspace.endNodes.clear();
|
||||||
workspace.links.clear();
|
workspace.links.clear();
|
||||||
|
|
||||||
for (auto &node : jsonData["nodes"]) {
|
try {
|
||||||
auto newNode = loadNode(node);
|
for (auto &node : jsonData["nodes"]) {
|
||||||
if (newNode == nullptr)
|
auto newNode = loadNode(node);
|
||||||
continue;
|
if (newNode == nullptr)
|
||||||
|
continue;
|
||||||
|
|
||||||
newNode->setPosition(ImVec2(node["pos"]["x"], node["pos"]["y"]));
|
newNode->setPosition(ImVec2(node["pos"]["x"], node["pos"]["y"]));
|
||||||
|
|
||||||
if (!node["data"].is_null())
|
if (!node["data"].is_null())
|
||||||
newNode->load(node["data"]);
|
newNode->load(node["data"]);
|
||||||
|
|
||||||
bool hasOutput = false;
|
bool hasOutput = false;
|
||||||
bool hasInput = false;
|
bool hasInput = false;
|
||||||
u32 attrIndex = 0;
|
u32 attrIndex = 0;
|
||||||
for (auto &attr : newNode->getAttributes()) {
|
for (auto &attr : newNode->getAttributes()) {
|
||||||
if (attr.getIOType() == dp::Attribute::IOType::Out)
|
if (attr.getIOType() == dp::Attribute::IOType::Out)
|
||||||
hasOutput = true;
|
hasOutput = true;
|
||||||
|
|
||||||
if (attr.getIOType() == dp::Attribute::IOType::In)
|
if (attr.getIOType() == dp::Attribute::IOType::In)
|
||||||
hasInput = true;
|
hasInput = true;
|
||||||
|
|
||||||
attr.setId(node["attrs"][attrIndex]);
|
attr.setId(node["attrs"][attrIndex]);
|
||||||
attrIndex++;
|
attrIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasInput && !hasOutput)
|
||||||
|
workspace.endNodes.push_back(newNode.get());
|
||||||
|
|
||||||
|
workspace.nodes.push_back(std::move(newNode));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasInput && !hasOutput)
|
int maxLinkId = 0;
|
||||||
workspace.endNodes.push_back(newNode.get());
|
for (auto &link : jsonData["links"]) {
|
||||||
|
dp::Link newLink(link["from"], link["to"]);
|
||||||
|
|
||||||
workspace.nodes.push_back(std::move(newNode));
|
int linkId = link["id"];
|
||||||
}
|
maxLinkId = std::max(linkId, maxLinkId);
|
||||||
|
|
||||||
int maxLinkId = 0;
|
newLink.setId(linkId);
|
||||||
for (auto &link : jsonData["links"]) {
|
workspace.links.push_back(newLink);
|
||||||
dp::Link newLink(link["from"], link["to"]);
|
|
||||||
|
|
||||||
int linkId = link["id"];
|
dp::Attribute *fromAttr = nullptr, *toAttr = nullptr;
|
||||||
maxLinkId = std::max(linkId, maxLinkId);
|
for (auto &node : workspace.nodes) {
|
||||||
|
for (auto &attribute : node->getAttributes()) {
|
||||||
|
if (attribute.getId() == newLink.getFromId())
|
||||||
|
fromAttr = &attribute;
|
||||||
|
else if (attribute.getId() == newLink.getToId())
|
||||||
|
toAttr = &attribute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newLink.setId(linkId);
|
if (fromAttr == nullptr || toAttr == nullptr)
|
||||||
workspace.links.push_back(newLink);
|
break;
|
||||||
|
|
||||||
dp::Attribute *fromAttr = nullptr, *toAttr = nullptr;
|
if (fromAttr->getType() != toAttr->getType())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (fromAttr->getIOType() == toAttr->getIOType())
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!toAttr->getConnectedAttributes().empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
fromAttr->addConnectedAttribute(newLink.getId(), toAttr);
|
||||||
|
toAttr->addConnectedAttribute(newLink.getId(), fromAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int maxNodeId = 0;
|
||||||
|
int maxAttrId = 0;
|
||||||
for (auto &node : workspace.nodes) {
|
for (auto &node : workspace.nodes) {
|
||||||
for (auto &attribute : node->getAttributes()) {
|
maxNodeId = std::max(maxNodeId, node->getId());
|
||||||
if (attribute.getId() == newLink.getFromId())
|
|
||||||
fromAttr = &attribute;
|
for (auto &attr : node->getAttributes()) {
|
||||||
else if (attribute.getId() == newLink.getToId())
|
maxAttrId = std::max(maxAttrId, attr.getId());
|
||||||
toAttr = &attribute;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fromAttr == nullptr || toAttr == nullptr)
|
dp::Node::setIdCounter(maxNodeId + 1);
|
||||||
break;
|
dp::Attribute::setIdCounter(maxAttrId + 1);
|
||||||
|
dp::Link::setIdCounter(maxLinkId + 1);
|
||||||
|
|
||||||
if (fromAttr->getType() != toAttr->getType())
|
ViewDataProcessor::processNodes(workspace);
|
||||||
break;
|
} catch (nlohmann::json::exception &e) {
|
||||||
|
PopupError::open(hex::format("Failed to load nodes: {}", e.what()));
|
||||||
if (fromAttr->getIOType() == toAttr->getIOType())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!toAttr->getConnectedAttributes().empty())
|
|
||||||
break;
|
|
||||||
|
|
||||||
fromAttr->addConnectedAttribute(newLink.getId(), toAttr);
|
|
||||||
toAttr->addConnectedAttribute(newLink.getId(), fromAttr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxNodeId = 0;
|
|
||||||
int maxAttrId = 0;
|
|
||||||
for (auto &node : workspace.nodes) {
|
|
||||||
maxNodeId = std::max(maxNodeId, node->getId());
|
|
||||||
|
|
||||||
for (auto &attr : node->getAttributes()) {
|
|
||||||
maxAttrId = std::max(maxAttrId, attr.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dp::Node::setIdCounter(maxNodeId + 1);
|
|
||||||
dp::Attribute::setIdCounter(maxAttrId + 1);
|
|
||||||
dp::Link::setIdCounter(maxLinkId + 1);
|
|
||||||
|
|
||||||
ViewDataProcessor::processNodes(workspace);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user