Fix recursive type checks/casts of broker data into type 'any'

This commit is contained in:
Jon Siwek 2018-09-10 14:55:13 -05:00
parent 3a824a06ed
commit 7e26bfe07f
5 changed files with 135 additions and 9 deletions

View file

@ -1,4 +1,10 @@
2.5-990 | 2018-09-10 14:55:13 -0500
* Fix recursive type checks/casts of broker data into type 'any' (Jon Siwek, Corelight)
* Fix is/as operators on vector values (Jon Siwek, Corelight)
2.5-988 | 2018-09-07 17:49:34 -0500
* Update default Broker/CAF thread tuning (Jon Siwek, Corelight)

View file

@ -1 +1 @@
2.5-988
2.5-990

View file

@ -14,6 +14,8 @@ OpaqueType* bro_broker::opaque_of_record_iterator;
BroType* bro_broker::DataVal::script_data_type = nullptr;
static bool data_type_check(const broker::data& d, BroType* t);
static broker::port::protocol to_broker_port_proto(TransportProto tp)
{
switch ( tp ) {
@ -624,7 +626,7 @@ struct type_checker {
auto expect = (*expected_index_types)[i];
auto& index_to_check = *(indices_to_check)[i];
if ( ! caf::visit(type_checker{expect}, index_to_check) )
if ( ! data_type_check(index_to_check, expect) )
return false;
}
}
@ -689,12 +691,11 @@ struct type_checker {
auto expect = (*expected_index_types)[i];
auto& index_to_check = *(indices_to_check)[i];
if ( ! caf::visit(type_checker{expect}, index_to_check) )
if ( ! data_type_check(index_to_check, expect) )
return false;
}
if ( ! caf::visit(type_checker{tt->YieldType()},
item.second) )
if ( ! data_type_check(item.second, tt->YieldType()) )
return false;
}
@ -709,7 +710,7 @@ struct type_checker {
for ( auto& item : a )
{
if ( ! caf::visit(type_checker{vt->YieldType()}, item) )
if ( ! data_type_check(item, vt->YieldType()) )
return false;
}
@ -731,8 +732,7 @@ struct type_checker {
continue;
}
if ( ! caf::visit(type_checker{rt->FieldType(i)},
a[idx]) )
if ( ! data_type_check(a[idx], rt->FieldType(i)) )
return false;
++idx;
@ -770,6 +770,14 @@ struct type_checker {
}
};
static bool data_type_check(const broker::data& d, BroType* t)
{
if ( t->Tag() == TYPE_ANY )
return true;
return caf::visit(type_checker{t}, d);
}
Val* bro_broker::data_to_val(broker::data d, BroType* type)
{
if ( type->Tag() == TYPE_ANY )
@ -1131,7 +1139,7 @@ broker::data& bro_broker::opaque_field_to_data(RecordVal* v, Frame* f)
bool bro_broker::DataVal::canCastTo(BroType* t) const
{
return caf::visit(type_checker{t}, data);
return data_type_check(data, t);
}
Val* bro_broker::DataVal::castTo(BroType* t)

View file

@ -0,0 +1,7 @@
count, 1
string, two
vector, [[data=broker::data{one}], [data=broker::data{two}], [data=broker::data{3}]]
string, one
string, two
count, 3
record, [a=bye, b=<uninitialized>, c=<uninitialized>]

View file

@ -0,0 +1,105 @@
# @TEST-SERIALIZE: comm
#
# @TEST-EXEC: btest-bg-run recv "bro -B broker -b ../recv.bro >recv.out"
# @TEST-EXEC: btest-bg-run send "bro -B broker -b ../send.bro >send.out"
#
# @TEST-EXEC: btest-bg-wait 20
# @TEST-EXEC: btest-diff recv/recv.out
@TEST-START-FILE send.bro
redef exit_only_after_terminate = T;
type myvec: vector of any;
type myrec: record {
a: string &optional;
b: count &optional;
c: int &optional;
};
global bar: event(x: any);
event bro_init()
{
Broker::subscribe("test");
Broker::peer("127.0.0.1");
}
event Broker::peer_added(endpoint: Broker::EndpointInfo, msg: string)
{
Broker::publish("test", bar, 1);
Broker::publish("test", bar, "two");
Broker::publish("test", bar, myvec("one", "two", 3));
Broker::publish("test", bar, myrec($a = "bye"));
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
terminate();
}
@TEST-END-FILE
@TEST-START-FILE recv.bro
redef exit_only_after_terminate = T;
type myvec: vector of any;
type myrec: record {
a: string &optional;
b: count &optional;
c: int &optional;
};
function process(x: any)
{
switch ( x ) {
case type myrec as r:
print "record", r;
if ( r$a == "bye" )
terminate();
break;
case type string as s:
print "string", s;
break;
case type int as i:
print "int", i;
break;
case type count as c:
print "count", c;
break;
case type myvec as v:
{
print "vector", v;
for ( i in v )
process(v[i]);
}
break;
default:
print "got unknown type", x;
break;
}
}
event bar(x: any)
{
process(x);
}
event bro_init()
{
Broker::subscribe("test");
Broker::listen();
}
event Broker::peer_lost(endpoint: Broker::EndpointInfo, msg: string)
{
terminate();
}
@TEST-END-FILE