diff --git a/CHANGES b/CHANGES index ec17130257..936c7788a3 100644 --- a/CHANGES +++ b/CHANGES @@ -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) diff --git a/VERSION b/VERSION index 78c217a878..3cc260ead4 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5-988 +2.5-990 diff --git a/src/broker/Data.cc b/src/broker/Data.cc index b836b66002..79fd0eba1a 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -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) diff --git a/testing/btest/Baseline/broker.remote_event_vector_any/recv.recv.out b/testing/btest/Baseline/broker.remote_event_vector_any/recv.recv.out new file mode 100644 index 0000000000..1981a334d4 --- /dev/null +++ b/testing/btest/Baseline/broker.remote_event_vector_any/recv.recv.out @@ -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=, c=] diff --git a/testing/btest/broker/remote_event_vector_any.bro b/testing/btest/broker/remote_event_vector_any.bro new file mode 100644 index 0000000000..ef79df7545 --- /dev/null +++ b/testing/btest/broker/remote_event_vector_any.bro @@ -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