mirror of https://github.com/WerWolv/ImHex.git
patterns: Added recursion and array size limit pragma
This commit is contained in:
parent
d1c05174b6
commit
755642862f
|
@ -821,6 +821,10 @@ namespace hex::pl {
|
||||||
[](auto &&size) -> u128 { return size; }
|
[](auto &&size) -> u128 { return size; }
|
||||||
}, literal->getValue());
|
}, literal->getValue());
|
||||||
|
|
||||||
|
auto limit = evaluator->getArrayLimit();
|
||||||
|
if (entryCount > limit)
|
||||||
|
LogConsole::abortEvaluation(hex::format("array grew past set limit of {}", limit), this);
|
||||||
|
|
||||||
for (u64 i = 0; i < entryCount; i++) {
|
for (u64 i = 0; i < entryCount; i++) {
|
||||||
auto pattern = this->m_type->createPatterns(evaluator).front();
|
auto pattern = this->m_type->createPatterns(evaluator).front();
|
||||||
|
|
||||||
|
@ -833,6 +837,10 @@ namespace hex::pl {
|
||||||
}
|
}
|
||||||
} else if (auto whileStatement = dynamic_cast<ASTNodeWhileStatement*>(sizeNode)) {
|
} else if (auto whileStatement = dynamic_cast<ASTNodeWhileStatement*>(sizeNode)) {
|
||||||
while (whileStatement->evaluateCondition(evaluator)) {
|
while (whileStatement->evaluateCondition(evaluator)) {
|
||||||
|
auto limit = evaluator->getArrayLimit();
|
||||||
|
if (entryCount > limit)
|
||||||
|
LogConsole::abortEvaluation(hex::format("array grew past set limit of {}", limit), this);
|
||||||
|
|
||||||
auto pattern = this->m_type->createPatterns(evaluator).front();
|
auto pattern = this->m_type->createPatterns(evaluator).front();
|
||||||
|
|
||||||
pattern->setVariableName(hex::format("[{}]", entryCount));
|
pattern->setVariableName(hex::format("[{}]", entryCount));
|
||||||
|
@ -846,6 +854,10 @@ namespace hex::pl {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (true) {
|
while (true) {
|
||||||
|
auto limit = evaluator->getArrayLimit();
|
||||||
|
if (entryCount > limit)
|
||||||
|
LogConsole::abortEvaluation(hex::format("array grew past set limit of {}", limit), this);
|
||||||
|
|
||||||
auto pattern = this->m_type->createPatterns(evaluator).front();
|
auto pattern = this->m_type->createPatterns(evaluator).front();
|
||||||
std::vector<u8> buffer(pattern->getSize());
|
std::vector<u8> buffer(pattern->getSize());
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
#include <hex/pattern_language/log_console.hpp>
|
#include <hex/pattern_language/log_console.hpp>
|
||||||
#include <hex/api/content_registry.hpp>
|
#include <hex/api/content_registry.hpp>
|
||||||
|
|
||||||
|
#include <hex/helpers/fmt.hpp>
|
||||||
|
|
||||||
namespace hex::prv { class Provider; }
|
namespace hex::prv { class Provider; }
|
||||||
|
|
||||||
namespace hex::pl {
|
namespace hex::pl {
|
||||||
|
@ -27,8 +29,17 @@ namespace hex::pl {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Scope { PatternData *parent; std::vector<PatternData*>* scope; };
|
struct Scope { PatternData *parent; std::vector<PatternData*>* scope; };
|
||||||
void pushScope(PatternData *parent, std::vector<PatternData*> &scope) { this->m_scopes.push_back({ parent, &scope }); }
|
void pushScope(PatternData *parent, std::vector<PatternData*> &scope) {
|
||||||
void popScope() { this->m_scopes.pop_back(); }
|
if (this->m_scopes.size() > this->m_evalDepth)
|
||||||
|
LogConsole::abortEvaluation(hex::format("recursion limit of {} reached", this->m_evalDepth));
|
||||||
|
|
||||||
|
this->m_scopes.push_back({ parent, &scope });
|
||||||
|
}
|
||||||
|
|
||||||
|
void popScope() {
|
||||||
|
this->m_scopes.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
const Scope& getScope(s32 index) {
|
const Scope& getScope(s32 index) {
|
||||||
static Scope empty;
|
static Scope empty;
|
||||||
|
|
||||||
|
@ -58,6 +69,24 @@ namespace hex::pl {
|
||||||
return this->m_defaultEndian;
|
return this->m_defaultEndian;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setEvaluationDepth(u32 evalDepth) {
|
||||||
|
this->m_evalDepth = evalDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
u32 getEvaluationDepth() const {
|
||||||
|
return this->m_evalDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setArrayLimit(u32 arrayLimit) {
|
||||||
|
this->m_arrayLimit = arrayLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
u32 getArrayLimit() const {
|
||||||
|
return this->m_arrayLimit;
|
||||||
|
}
|
||||||
|
|
||||||
u64& dataOffset() { return this->m_currOffset; }
|
u64& dataOffset() { return this->m_currOffset; }
|
||||||
|
|
||||||
bool addCustomFunction(const std::string &name, u32 numParams, const ContentRegistry::PatternLanguageFunctions::Callback &function) {
|
bool addCustomFunction(const std::string &name, u32 numParams, const ContentRegistry::PatternLanguageFunctions::Callback &function) {
|
||||||
|
@ -86,6 +115,8 @@ namespace hex::pl {
|
||||||
LogConsole m_console;
|
LogConsole m_console;
|
||||||
|
|
||||||
std::endian m_defaultEndian = std::endian::native;
|
std::endian m_defaultEndian = std::endian::native;
|
||||||
|
u32 m_evalDepth;
|
||||||
|
u32 m_arrayLimit;
|
||||||
|
|
||||||
std::vector<Scope> m_scopes;
|
std::vector<Scope> m_scopes;
|
||||||
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> m_customFunctions;
|
std::map<std::string, ContentRegistry::PatternLanguageFunctions::Function> m_customFunctions;
|
||||||
|
|
|
@ -45,7 +45,8 @@ namespace hex::pl {
|
||||||
|
|
||||||
prv::Provider *m_provider = nullptr;
|
prv::Provider *m_provider = nullptr;
|
||||||
std::endian m_defaultEndian = std::endian::native;
|
std::endian m_defaultEndian = std::endian::native;
|
||||||
u32 m_recursionLimit = 32;
|
u32 m_evalDepth;
|
||||||
|
u32 m_arrayLimit;
|
||||||
|
|
||||||
std::optional<std::pair<u32, std::string>> m_currError;
|
std::optional<std::pair<u32, std::string>> m_currError;
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,17 @@ namespace hex::pl {
|
||||||
if (limit <= 0)
|
if (limit <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this->m_recursionLimit = limit;
|
this->m_evalDepth = limit;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
this->m_preprocessor->addPragmaHandler("array_limit", [this](std::string value) {
|
||||||
|
auto limit = strtol(value.c_str(), nullptr, 0);
|
||||||
|
|
||||||
|
if (limit <= 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this->m_arrayLimit = limit;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -69,6 +79,8 @@ namespace hex::pl {
|
||||||
this->m_currError.reset();
|
this->m_currError.reset();
|
||||||
this->m_evaluator->getConsole().clear();
|
this->m_evaluator->getConsole().clear();
|
||||||
this->m_evaluator->setProvider(provider);
|
this->m_evaluator->setProvider(provider);
|
||||||
|
this->m_evalDepth = 32;
|
||||||
|
this->m_arrayLimit = 0x1000;
|
||||||
|
|
||||||
for (auto &node : this->m_currAST)
|
for (auto &node : this->m_currAST)
|
||||||
delete node;
|
delete node;
|
||||||
|
@ -81,7 +93,8 @@ namespace hex::pl {
|
||||||
}
|
}
|
||||||
|
|
||||||
this->m_evaluator->setDefaultEndian(this->m_defaultEndian);
|
this->m_evaluator->setDefaultEndian(this->m_defaultEndian);
|
||||||
// this->m_evaluator->setRecursionLimit(this->m_recursionLimit);
|
this->m_evaluator->setEvaluationDepth(this->m_evalDepth);
|
||||||
|
this->m_evaluator->setArrayLimit(this->m_arrayLimit);
|
||||||
|
|
||||||
auto tokens = this->m_lexer->lex(preprocessedCode.value());
|
auto tokens = this->m_lexer->lex(preprocessedCode.value());
|
||||||
if (!tokens.has_value()) {
|
if (!tokens.has_value()) {
|
||||||
|
|
Loading…
Reference in New Issue