ApplyRule::GetTarget*s(): support constant strings from variables

in addition to literal strings. This is for sandboxed filters with some
variables pre-set by the caller. They're "constant" in that scope, too.
This commit is contained in:
Alexander A. Klimov 2023-11-21 14:36:32 +01:00
parent a04cef1890
commit 15191bcd74
2 changed files with 46 additions and 33 deletions

View File

@ -96,16 +96,16 @@ bool ApplyRule::AddTargetedRule(const ApplyRule::Ptr& rule, const String& target
* *
* @returns Whether the given assign filter is like above. * @returns Whether the given assign filter is like above.
*/ */
bool ApplyRule::GetTargetHosts(Expression* assignFilter, std::vector<const String *>& hosts) bool ApplyRule::GetTargetHosts(Expression* assignFilter, std::vector<const String *>& hosts, const Dictionary::Ptr& constants)
{ {
auto lor (dynamic_cast<LogicalOrExpression*>(assignFilter)); auto lor (dynamic_cast<LogicalOrExpression*>(assignFilter));
if (lor) { if (lor) {
return GetTargetHosts(lor->GetOperand1().get(), hosts) return GetTargetHosts(lor->GetOperand1().get(), hosts, constants)
&& GetTargetHosts(lor->GetOperand2().get(), hosts); && GetTargetHosts(lor->GetOperand2().get(), hosts, constants);
} }
auto name (GetComparedName(assignFilter, "host")); auto name (GetComparedName(assignFilter, "host", constants));
if (name) { if (name) {
hosts.emplace_back(name); hosts.emplace_back(name);
@ -124,16 +124,16 @@ bool ApplyRule::GetTargetHosts(Expression* assignFilter, std::vector<const Strin
* *
* @returns Whether the given assign filter is like above. * @returns Whether the given assign filter is like above.
*/ */
bool ApplyRule::GetTargetServices(Expression* assignFilter, std::vector<std::pair<const String *, const String *>>& services) bool ApplyRule::GetTargetServices(Expression* assignFilter, std::vector<std::pair<const String *, const String *>>& services, const Dictionary::Ptr& constants)
{ {
auto lor (dynamic_cast<LogicalOrExpression*>(assignFilter)); auto lor (dynamic_cast<LogicalOrExpression*>(assignFilter));
if (lor) { if (lor) {
return GetTargetServices(lor->GetOperand1().get(), services) return GetTargetServices(lor->GetOperand1().get(), services, constants)
&& GetTargetServices(lor->GetOperand2().get(), services); && GetTargetServices(lor->GetOperand2().get(), services, constants);
} }
auto service (GetTargetService(assignFilter)); auto service (GetTargetService(assignFilter, constants));
if (service.first) { if (service.first) {
services.emplace_back(service); services.emplace_back(service);
@ -152,7 +152,7 @@ bool ApplyRule::GetTargetServices(Expression* assignFilter, std::vector<std::pai
* *
* @returns {host, service} on success and {nullptr, nullptr} on failure. * @returns {host, service} on success and {nullptr, nullptr} on failure.
*/ */
std::pair<const String *, const String *> ApplyRule::GetTargetService(Expression* assignFilter) std::pair<const String *, const String *> ApplyRule::GetTargetService(Expression* assignFilter, const Dictionary::Ptr& constants)
{ {
auto land (dynamic_cast<LogicalAndExpression*>(assignFilter)); auto land (dynamic_cast<LogicalAndExpression*>(assignFilter));
@ -162,15 +162,15 @@ std::pair<const String *, const String *> ApplyRule::GetTargetService(Expression
auto op1 (land->GetOperand1().get()); auto op1 (land->GetOperand1().get());
auto op2 (land->GetOperand2().get()); auto op2 (land->GetOperand2().get());
auto host (GetComparedName(op1, "host")); auto host (GetComparedName(op1, "host", constants));
if (!host) { if (!host) {
std::swap(op1, op2); std::swap(op1, op2);
host = GetComparedName(op1, "host"); host = GetComparedName(op1, "host", constants);
} }
if (host) { if (host) {
auto service (GetComparedName(op2, "service")); auto service (GetComparedName(op2, "service", constants));
if (service) { if (service) {
return {host, service}; return {host, service};
@ -189,7 +189,7 @@ std::pair<const String *, const String *> ApplyRule::GetTargetService(Expression
* *
* @returns The object name on success and nullptr on failure. * @returns The object name on success and nullptr on failure.
*/ */
const String * ApplyRule::GetComparedName(Expression* assignFilter, const char * lcType) const String * ApplyRule::GetComparedName(Expression* assignFilter, const char * lcType, const Dictionary::Ptr& constants)
{ {
auto eq (dynamic_cast<EqualExpression*>(assignFilter)); auto eq (dynamic_cast<EqualExpression*>(assignFilter));
@ -200,12 +200,12 @@ const String * ApplyRule::GetComparedName(Expression* assignFilter, const char *
auto op1 (eq->GetOperand1().get()); auto op1 (eq->GetOperand1().get());
auto op2 (eq->GetOperand2().get()); auto op2 (eq->GetOperand2().get());
if (IsNameIndexer(op1, lcType)) { if (IsNameIndexer(op1, lcType, constants)) {
return GetLiteralStringValue(op2); return GetConstString(op2, constants);
} }
if (IsNameIndexer(op2, lcType)) { if (IsNameIndexer(op2, lcType, constants)) {
return GetLiteralStringValue(op1); return GetConstString(op1, constants);
} }
return nullptr; return nullptr;
@ -214,7 +214,7 @@ const String * ApplyRule::GetComparedName(Expression* assignFilter, const char *
/** /**
* @returns Whether the given expression is like $lcType$.name. * @returns Whether the given expression is like $lcType$.name.
*/ */
bool ApplyRule::IsNameIndexer(Expression* exp, const char * lcType) bool ApplyRule::IsNameIndexer(Expression* exp, const char * lcType, const Dictionary::Ptr& constants)
{ {
auto ixr (dynamic_cast<IndexerExpression*>(exp)); auto ixr (dynamic_cast<IndexerExpression*>(exp));
@ -228,27 +228,39 @@ bool ApplyRule::IsNameIndexer(Expression* exp, const char * lcType)
return false; return false;
} }
auto val (GetLiteralStringValue(ixr->GetOperand2().get())); auto val (GetConstString(ixr->GetOperand2().get(), constants));
return val && *val == "name"; return val && *val == "name";
} }
/** /**
* @returns If the given expression is a string literal, the string. nullptr on failure. * @returns If the given expression is a constant string, its address. nullptr on failure.
*/ */
const String * ApplyRule::GetLiteralStringValue(Expression* exp) const String * ApplyRule::GetConstString(Expression* exp, const Dictionary::Ptr& constants)
{
auto cnst (GetConst(exp, constants));
return cnst && cnst->IsString() ? &cnst->Get<String>() : nullptr;
}
/**
* @returns If the given expression is a constant, its address. nullptr on failure.
*/
const Value * ApplyRule::GetConst(Expression* exp, const Dictionary::Ptr& constants)
{ {
auto lit (dynamic_cast<LiteralExpression*>(exp)); auto lit (dynamic_cast<LiteralExpression*>(exp));
if (!lit) { if (lit) {
return nullptr; return &lit->GetValue();
} }
auto& val (lit->GetValue()); if (constants) {
auto var (dynamic_cast<VariableExpression*>(exp));
if (!val.IsString()) { if (var) {
return nullptr; return constants->GetRef(var->GetVariable());
}
} }
return &val.Get<String>(); return nullptr;
} }

View File

@ -108,12 +108,13 @@ private:
static RuleMap m_Rules; static RuleMap m_Rules;
static bool AddTargetedRule(const ApplyRule::Ptr& rule, const String& targetType, PerSourceType& rules); static bool AddTargetedRule(const ApplyRule::Ptr& rule, const String& targetType, PerSourceType& rules);
static bool GetTargetHosts(Expression* assignFilter, std::vector<const String *>& hosts); static bool GetTargetHosts(Expression* assignFilter, std::vector<const String *>& hosts, const Dictionary::Ptr& constants = nullptr);
static bool GetTargetServices(Expression* assignFilter, std::vector<std::pair<const String *, const String *>>& services); static bool GetTargetServices(Expression* assignFilter, std::vector<std::pair<const String *, const String *>>& services, const Dictionary::Ptr& constants = nullptr);
static std::pair<const String *, const String *> GetTargetService(Expression* assignFilter); static std::pair<const String *, const String *> GetTargetService(Expression* assignFilter, const Dictionary::Ptr& constants);
static const String * GetComparedName(Expression* assignFilter, const char * lcType); static const String * GetComparedName(Expression* assignFilter, const char * lcType, const Dictionary::Ptr& constants);
static bool IsNameIndexer(Expression* exp, const char * lcType); static bool IsNameIndexer(Expression* exp, const char * lcType, const Dictionary::Ptr& constants);
static const String * GetLiteralStringValue(Expression* exp); static const String * GetConstString(Expression* exp, const Dictionary::Ptr& constants);
static const Value * GetConst(Expression* exp, const Dictionary::Ptr& constants);
ApplyRule(String name, Expression::Ptr expression, ApplyRule(String name, Expression::Ptr expression,
Expression::Ptr filter, String package, String fkvar, String fvvar, Expression::Ptr fterm, Expression::Ptr filter, String package, String fkvar, String fvvar, Expression::Ptr fterm,