Analyzer: Add GetChildAnalyzer() and IsPreventedChildAnalyzer()

GetChildAnalyzer() has the same semantics as HasChildAnalyzer(), but returns
the raw pointer to the child analyzer. Main issue is memory management: That
pointer is not guaranteed to stay valid. It might be disabled from script
land or otherwise removed from the analyzer tree and subsequent
deleted in one of the Forward* methods.

IsPreventedChildAnalyzer() provides minimal introspection for prevented
child analyzer tags and allows to remove some duplicated code.
This commit is contained in:
Arne Welzel 2023-03-29 10:28:30 +02:00
parent 2f5b9ce038
commit b03e678438
2 changed files with 42 additions and 16 deletions

View file

@ -386,10 +386,8 @@ void Analyzer::ForwardEndOfData(bool orig)
bool Analyzer::AddChildAnalyzer(Analyzer* analyzer, bool init)
{
auto t = analyzer->GetAnalyzerTag();
auto it = std::find(prevented.begin(), prevented.end(), t);
auto prevent = (it != prevented.end());
if ( HasChildAnalyzer(t) || prevent )
if ( HasChildAnalyzer(t) || IsPreventedChildAnalyzer(t) )
{
analyzer->Done();
delete analyzer;
@ -418,9 +416,7 @@ Analyzer* Analyzer::AddChildAnalyzer(const zeek::Tag& analyzer)
if ( HasChildAnalyzer(analyzer) )
return nullptr;
auto it = std::find(prevented.begin(), prevented.end(), analyzer);
if ( it != prevented.end() )
if ( IsPreventedChildAnalyzer(tag) )
return nullptr;
Analyzer* a = analyzer_mgr->InstantiateAnalyzer(analyzer, conn);
@ -468,27 +464,35 @@ bool Analyzer::Remove()
return removing;
}
void Analyzer::PreventChildren(zeek::Tag tag)
void Analyzer::PreventChildren(const zeek::Tag& tag)
{
auto it = std::find(prevented.begin(), prevented.end(), tag);
if ( it != prevented.end() )
if ( IsPreventedChildAnalyzer(tag) )
return;
prevented.emplace_back(tag);
}
bool Analyzer::HasChildAnalyzer(zeek::Tag tag)
bool Analyzer::IsPreventedChildAnalyzer(const zeek::Tag& tag) const
{
return std::find(prevented.begin(), prevented.end(), tag) != prevented.end();
}
bool Analyzer::HasChildAnalyzer(const zeek::Tag& tag) const
{
return GetChildAnalyzer(tag) != nullptr;
}
Analyzer* Analyzer::GetChildAnalyzer(const zeek::Tag& tag) const
{
LOOP_OVER_CHILDREN(i)
if ( (*i)->tag == tag && ! ((*i)->removing || (*i)->finished) )
return true;
return *i;
LOOP_OVER_GIVEN_CHILDREN(i, new_children)
if ( (*i)->tag == tag && ! ((*i)->removing || (*i)->finished) )
return true;
return *i;
return false;
return nullptr;
}
Analyzer* Analyzer::FindChild(ID arg_id)

View file

@ -434,14 +434,36 @@ public:
*
* @param tag The type of analyzer to prevent.
*/
void PreventChildren(zeek::Tag tag);
void PreventChildren(const zeek::Tag& tag);
/**
* Returns true if the given analyzer type is prevented from
* being added as a child.
*
* @param tag The type of analyzer to prevent.
*
* @return true if the analyzer type is prevented, else false.
*/
bool IsPreventedChildAnalyzer(const zeek::Tag& tag) const;
/**
* Returns true if analyzer has a direct child of a given type.
*
* @param tag The type of analyzer to check for.
*/
bool HasChildAnalyzer(zeek::Tag tag);
bool HasChildAnalyzer(const zeek::Tag& tag) const;
/**
* Returns a pointer to a direct child analyzer of the given type.
*
* Note that the returned pointer is owned by the analyzer and may
* be deleted without notification. Do not hold on to it.
*
* @param tag The type of the analyzer to check for.
*
* @return The analyzer, or null if not found.
*/
Analyzer* GetChildAnalyzer(const zeek::Tag& tag) const;
/**
* Recursively searches all (direct or indirect) childs of the