diff --git a/userspace/engine/falco_source.h b/userspace/engine/falco_source.h index d443b2ba..b222054e 100644 --- a/userspace/engine/falco_source.h +++ b/userspace/engine/falco_source.h @@ -56,12 +56,30 @@ struct falco_source // matches an event. mutable std::vector m_rules; - inline bool is_field_defined(const std::string& field) const + inline bool is_valid_lhs_field(const std::string& field) const { - if (filter_factory->new_filtercheck(field.c_str()) != nullptr) + // if there's at least one parenthesis we may be parsing a field + // wrapped inside one or more transformers. In those cases, the most + // rigorous analysis we can do is compiling a simple filter using + // the field as left-hand side of a comparison, and see if any error + // occurs. + if (field.find('(') != std::string::npos) { - return true; + try + { + auto filter = field; + filter.append(" exists"); + sinsp_filter_compiler(filter_factory, filter).compile(); + return true; + } + catch (...) + { + return false; + } } - return false; + + // otherwise, simply attempt creating a filtercheck with the given + // field name and see if we succeed + return filter_factory->new_filtercheck(field.c_str()) != nullptr; } }; diff --git a/userspace/engine/rule_loader_collector.cpp b/userspace/engine/rule_loader_collector.cpp index 1832e1b6..394e8a79 100644 --- a/userspace/engine/rule_loader_collector.cpp +++ b/userspace/engine/rule_loader_collector.cpp @@ -88,7 +88,7 @@ static void validate_exception_info( { for (const auto &v : ex.fields.items) { - THROW(!source->is_field_defined(v.item), + THROW(!source->is_valid_lhs_field(v.item), std::string("'") + v.item + "' is not a supported filter field", ex.ctx); } @@ -109,7 +109,7 @@ static void validate_exception_info( ex.ctx); if (source) { - THROW(!source->is_field_defined(ex.fields.item), + THROW(!source->is_valid_lhs_field(ex.fields.item), std::string("'") + ex.fields.item + "' is not a supported filter field", ex.ctx); }