Fix crash when printing type of recursive structures.

Also slightly fix indentation in Type.h
This commit is contained in:
Johanna Amann 2016-02-03 13:22:05 -08:00
parent 13c4489578
commit c5a14d1bc1
6 changed files with 50 additions and 6 deletions

View file

@ -351,3 +351,24 @@ void ODesc::Clear()
} }
} }
bool ODesc::PushType(const BroType* type)
{
auto res = encountered_types.insert(type);
return std::get<1>(res);
}
bool ODesc::PopType(const BroType* type)
{
size_t res = encountered_types.erase(type);
return (res == 1);
}
bool ODesc::FindType(const BroType* type)
{
auto res = encountered_types.find(type);
if ( res != encountered_types.end() )
return true;
return false;
}

View file

@ -23,6 +23,7 @@ typedef enum {
class BroFile; class BroFile;
class IPAddr; class IPAddr;
class IPPrefix; class IPPrefix;
class BroType;
class ODesc { class ODesc {
public: public:
@ -140,6 +141,12 @@ public:
void Clear(); void Clear();
// Used to determine recursive types. Records push their types on here;
// if the same type (by address) is re-encountered, processing aborts.
bool PushType(const BroType* type);
bool PopType(const BroType* type);
bool FindType(const BroType* type);
protected: protected:
void Indent(); void Indent();
@ -190,6 +197,8 @@ protected:
int do_flush; int do_flush;
int include_stats; int include_stats;
int indent_with_spaces; int indent_with_spaces;
std::set<const BroType*> encountered_types;
}; };
#endif #endif

View file

@ -1045,6 +1045,7 @@ TypeDecl* RecordType::FieldDecl(int field)
void RecordType::Describe(ODesc* d) const void RecordType::Describe(ODesc* d) const
{ {
d->PushType(this);
if ( d->IsReadable() ) if ( d->IsReadable() )
{ {
if ( d->IsShort() && GetName().size() ) if ( d->IsShort() && GetName().size() )
@ -1064,10 +1065,12 @@ void RecordType::Describe(ODesc* d) const
d->Add(int(Tag())); d->Add(int(Tag()));
DescribeFields(d); DescribeFields(d);
} }
d->PopType(this);
} }
void RecordType::DescribeReST(ODesc* d, bool roles_only) const void RecordType::DescribeReST(ODesc* d, bool roles_only) const
{ {
d->PushType(this);
d->Add(":bro:type:`record`"); d->Add(":bro:type:`record`");
if ( num_fields == 0 ) if ( num_fields == 0 )
@ -1075,6 +1078,7 @@ void RecordType::DescribeReST(ODesc* d, bool roles_only) const
d->NL(); d->NL();
DescribeFieldsReST(d, false); DescribeFieldsReST(d, false);
d->PopType(this);
} }
const char* RecordType::AddFields(type_decl_list* others, attr_list* attr) const char* RecordType::AddFields(type_decl_list* others, attr_list* attr)
@ -1129,6 +1133,9 @@ void RecordType::DescribeFields(ODesc* d) const
const TypeDecl* td = FieldDecl(i); const TypeDecl* td = FieldDecl(i);
d->Add(td->id); d->Add(td->id);
d->Add(":"); d->Add(":");
if ( d->FindType(td->type) )
d->Add("<recursion>");
else
td->type->Describe(d); td->type->Describe(d);
d->Add(";"); d->Add(";");
} }
@ -1170,6 +1177,9 @@ void RecordType::DescribeFieldsReST(ODesc* d, bool func_args) const
} }
const TypeDecl* td = FieldDecl(i); const TypeDecl* td = FieldDecl(i);
if ( d->FindType(td->type) )
d->Add("<recursion>");
else
td->DescribeReST(d); td->DescribeReST(d);
if ( func_args ) if ( func_args )

View file

@ -182,6 +182,7 @@ public:
CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType"); CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType");
return (const FuncType*) this; return (const FuncType*) this;
} }
FuncType* AsFuncType() FuncType* AsFuncType()
{ {
CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType"); CHECK_TYPE_TAG(TYPE_FUNC, "BroType::AsFuncType");

View file

@ -0,0 +1,2 @@
[id=<uninitialized>, inner=<uninitialized>]
record { id:count; inner:record { create:function(input:<recursion>;) : string; }; }

View file

@ -16,4 +16,5 @@ redef record Outer += {
event bro_init() { event bro_init() {
local o = Outer(); local o = Outer();
print o; print o;
print type_name(o);
} }