mirror of
https://github.com/zeek/zeek.git
synced 2025-10-12 03:28:19 +00:00
fix for sets containing recursive records
This commit is contained in:
parent
aa5a5b2136
commit
f7581437d9
2 changed files with 26 additions and 11 deletions
31
src/Val.cc
31
src/Val.cc
|
@ -1367,7 +1367,10 @@ static void table_entry_val_delete_func(void* val)
|
||||||
delete tv;
|
delete tv;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_nested_record_types(const TypePtr& t, std::set<RecordType*>* found)
|
// Third argument tracks records currently being analyzed, to avoid infinite
|
||||||
|
// loops in the face of recursive records.
|
||||||
|
static void find_nested_record_types(const TypePtr& t, std::set<RecordType*>* found,
|
||||||
|
std::set<const RecordType*>* analyzed_records)
|
||||||
{
|
{
|
||||||
if ( ! t )
|
if ( ! t )
|
||||||
return;
|
return;
|
||||||
|
@ -1377,31 +1380,38 @@ static void find_nested_record_types(const TypePtr& t, std::set<RecordType*>* fo
|
||||||
case TYPE_RECORD:
|
case TYPE_RECORD:
|
||||||
{
|
{
|
||||||
auto rt = t->AsRecordType();
|
auto rt = t->AsRecordType();
|
||||||
|
|
||||||
|
if ( analyzed_records->count(rt) > 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
analyzed_records->insert(rt);
|
||||||
found->emplace(rt);
|
found->emplace(rt);
|
||||||
|
|
||||||
for ( auto i = 0; i < rt->NumFields(); ++i )
|
for ( auto i = 0; i < rt->NumFields(); ++i )
|
||||||
find_nested_record_types(rt->FieldDecl(i)->type, found);
|
find_nested_record_types(rt->FieldDecl(i)->type, found, analyzed_records);
|
||||||
|
|
||||||
|
analyzed_records->erase(rt);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TYPE_TABLE:
|
case TYPE_TABLE:
|
||||||
find_nested_record_types(t->AsTableType()->GetIndices(), found);
|
find_nested_record_types(t->AsTableType()->GetIndices(), found, analyzed_records);
|
||||||
find_nested_record_types(t->AsTableType()->Yield(), found);
|
find_nested_record_types(t->AsTableType()->Yield(), found, analyzed_records);
|
||||||
return;
|
return;
|
||||||
case TYPE_LIST:
|
case TYPE_LIST:
|
||||||
{
|
{
|
||||||
for ( const auto& type : t->AsTypeList()->GetTypes() )
|
for ( const auto& type : t->AsTypeList()->GetTypes() )
|
||||||
find_nested_record_types(type, found);
|
find_nested_record_types(type, found, analyzed_records);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case TYPE_FUNC:
|
case TYPE_FUNC:
|
||||||
find_nested_record_types(t->AsFuncType()->Params(), found);
|
find_nested_record_types(t->AsFuncType()->Params(), found, analyzed_records);
|
||||||
find_nested_record_types(t->AsFuncType()->Yield(), found);
|
find_nested_record_types(t->AsFuncType()->Yield(), found, analyzed_records);
|
||||||
return;
|
return;
|
||||||
case TYPE_VECTOR:
|
case TYPE_VECTOR:
|
||||||
find_nested_record_types(t->AsVectorType()->Yield(), found);
|
find_nested_record_types(t->AsVectorType()->Yield(), found, analyzed_records);
|
||||||
return;
|
return;
|
||||||
case TYPE_TYPE:
|
case TYPE_TYPE:
|
||||||
find_nested_record_types(t->AsTypeType()->GetType(), found);
|
find_nested_record_types(t->AsTypeType()->GetType(), found, analyzed_records);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
@ -1419,9 +1429,10 @@ TableVal::TableVal(TableTypePtr t, detail::AttributesPtr a) : Val(t)
|
||||||
for ( const auto& t : table_type->GetIndexTypes() )
|
for ( const auto& t : table_type->GetIndexTypes() )
|
||||||
{
|
{
|
||||||
std::set<RecordType*> found;
|
std::set<RecordType*> found;
|
||||||
|
std::set<const RecordType*> analyzed_records;
|
||||||
// TODO: this likely doesn't have to be repeated for each new TableVal,
|
// TODO: this likely doesn't have to be repeated for each new TableVal,
|
||||||
// can remember the resulting dependencies per TableType
|
// can remember the resulting dependencies per TableType
|
||||||
find_nested_record_types(t, &found);
|
find_nested_record_types(t, &found, &analyzed_records);
|
||||||
|
|
||||||
for ( auto rt : found )
|
for ( auto rt : found )
|
||||||
parse_time_table_record_dependencies[rt].emplace_back(NewRef{}, this);
|
parse_time_table_record_dependencies[rt].emplace_back(NewRef{}, this);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# @TEST-EXEC: zeek -b %INPUT >output 2>&1
|
# @TEST-EXEC: zeek %INPUT >output 2>&1
|
||||||
# @TEST-EXEC: btest-diff output
|
# @TEST-EXEC: btest-diff output
|
||||||
|
|
||||||
# Make sure a set can be indexed with a record that has optional fields
|
# Make sure a set can be indexed with a record that has optional fields
|
||||||
|
@ -53,3 +53,7 @@ event zeek_init()
|
||||||
print f3 in set_of_foo;
|
print f3 in set_of_foo;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Also make sure that we can declare sets of recursive records.
|
||||||
|
# This used to crash in Zeek 4.x.
|
||||||
|
global crash_me: set[Conn::RemovalHook];
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue