patterns: Limit max number of patterns

Can be overriden with the pattern_limit pragma
Further improves situation with #313
This commit is contained in:
WerWolv
2021-10-02 15:22:38 +02:00
parent aef959854f
commit 12a8cadcfe
7 changed files with 204 additions and 75 deletions

View File

@@ -21,19 +21,21 @@ namespace hex::pl {
LogConsole::abortEvaluation("cannot determine type of auto variable", type);
if (std::get_if<u128>(&*value) != nullptr)
pattern = new PatternDataUnsigned(0, sizeof(u128));
pattern = new PatternDataUnsigned(0, sizeof(u128), this);
else if (std::get_if<s128>(&*value) != nullptr)
pattern = new PatternDataSigned(0, sizeof(s128));
pattern = new PatternDataSigned(0, sizeof(s128), this);
else if (std::get_if<double>(&*value) != nullptr)
pattern = new PatternDataFloat(0, sizeof(double));
pattern = new PatternDataFloat(0, sizeof(double), this);
else if (std::get_if<bool>(&*value) != nullptr)
pattern = new PatternDataBoolean(0);
pattern = new PatternDataBoolean(0, this);
else if (std::get_if<char>(&*value) != nullptr)
pattern = new PatternDataCharacter(0);
pattern = new PatternDataCharacter(0, this);
else if (std::get_if<PatternData*>(&*value) != nullptr)
pattern = std::get<PatternData*>(*value)->clone();
else if (std::get_if<std::string>(&*value) != nullptr)
pattern = new PatternDataString(0, 1);
pattern = new PatternDataString(0, 1, this);
else
__builtin_unreachable();
}
pattern->setVariableName(name);
@@ -106,6 +108,7 @@ namespace hex::pl {
this->m_scopes.clear();
this->dataOffset() = 0x00;
this->m_currPatternCount = 0;
for (auto &func : this->m_customFunctionDefinitions)
delete func;
@@ -139,10 +142,22 @@ namespace hex::pl {
delete pattern;
patterns.clear();
this->m_currPatternCount = 0;
return std::nullopt;
}
return patterns;
}
void Evaluator::patternCreated() {
if (this->m_currPatternCount > this->m_patternLimit)
LogConsole::abortEvaluation(hex::format("exceeded maximum number of patterns: {}", this->m_patternLimit));
this->m_currPatternCount++;
}
void Evaluator::patternDestroyed() {
this->m_currPatternCount--;
}
}

View File

@@ -43,21 +43,31 @@ namespace hex::pl {
if (limit <= 0)
return false;
this->m_evalDepth = limit;
this->m_evaluator->setEvaluationDepth(limit);
return true;
});
this->m_preprocessor->addPragmaHandler("array_limit", [this](std::string value) {
this->m_preprocessor->addPragmaHandler("array_limit", [this](const std::string &value) {
auto limit = strtol(value.c_str(), nullptr, 0);
if (limit <= 0)
return false;
this->m_arrayLimit = limit;
this->m_evaluator->setArrayLimit(limit);
return true;
});
this->m_preprocessor->addPragmaHandler("base_address", [](std::string value) {
this->m_preprocessor->addPragmaHandler("pattern_limit", [this](const std::string &value) {
auto limit = strtol(value.c_str(), nullptr, 0);
if (limit <= 0)
return false;
this->m_evaluator->setPatternLimit(limit);
return true;
});
this->m_preprocessor->addPragmaHandler("base_address", [](const std::string &value) {
auto baseAddress = strtoull(value.c_str(), nullptr, 0);
ImHexApi::Provider::get()->setBaseAddress(baseAddress);
@@ -79,8 +89,10 @@ namespace hex::pl {
this->m_currError.reset();
this->m_evaluator->getConsole().clear();
this->m_evaluator->setProvider(provider);
this->m_evalDepth = 32;
this->m_arrayLimit = 0x1000;
this->m_evaluator->setDefaultEndian(std::endian::native);
this->m_evaluator->setEvaluationDepth(32);
this->m_evaluator->setArrayLimit(0x1000);
this->m_evaluator->setPatternLimit(0x2000);
for (auto &node : this->m_currAST)
delete node;
@@ -92,10 +104,6 @@ namespace hex::pl {
return { };
}
this->m_evaluator->setDefaultEndian(this->m_defaultEndian);
this->m_evaluator->setEvaluationDepth(this->m_evalDepth);
this->m_evaluator->setArrayLimit(this->m_arrayLimit);
auto tokens = this->m_lexer->lex(preprocessedCode.value());
if (!tokens.has_value()) {
this->m_currError = this->m_lexer->getError();
@@ -134,4 +142,12 @@ namespace hex::pl {
return this->m_currError;
}
u32 PatternLanguage::getCreatedPatternCount() {
return this->m_evaluator->getPatternCount();
}
u32 PatternLanguage::getMaximumPatternCount() {
return this->m_evaluator->getPatternLimit();
}
}