diff --git a/CHANGES b/CHANGES index 32b7c8cbc2..af9f1b88f5 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,9 @@ +2.5-842 | 2018-08-15 11:00:20 -0500 + + * Fix seg fault on trying to type-cast invalid/nil Broker::Data + (Jon Siwek, Corelight) + 2.5-841 | 2018-08-14 16:45:09 -0500 * BIT-1798: fix PPTP GRE tunnel decapsulation (Jon Siwek, Corelight) diff --git a/VERSION b/VERSION index 7a93a5255d..4744b3cd09 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5-841 +2.5-842 diff --git a/src/Expr.cc b/src/Expr.cc index f958c63ecf..07034db1a8 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -16,6 +16,8 @@ #include "Trigger.h" #include "IPAddr.h" +#include "broker/Data.h" + const char* expr_name(BroExprTag t) { static const char* expr_names[int(NUM_EXPRS)] = { @@ -5503,11 +5505,16 @@ Val* CastExpr::Eval(Frame* f) const } ODesc d; - d.Add("cannot cast value of type '"); + d.Add("invalid cast of value with type '"); v->Type()->Describe(&d); d.Add("' to type '"); Type()->Describe(&d); d.Add("'"); + + if ( same_type(v->Type(), bro_broker::DataVal::ScriptDataType()) && + ! v->AsRecordVal()->Lookup(0) ) + d.Add(" (nil $data field)"); + Unref(v); reporter->ExprRuntimeError(this, "%s", d.Description()); return 0; // not reached. diff --git a/src/Val.cc b/src/Val.cc index 1024251418..7879d282b2 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -3632,6 +3632,10 @@ Val* cast_value_to_type(Val* v, BroType* t) if ( same_type(v->Type(), bro_broker::DataVal::ScriptDataType()) ) { auto dv = v->AsRecordVal()->Lookup(0); + + if ( ! dv ) + return 0; + return static_cast(dv)->castTo(t); } @@ -3654,6 +3658,10 @@ bool can_cast_value_to_type(const Val* v, BroType* t) if ( same_type(v->Type(), bro_broker::DataVal::ScriptDataType()) ) { auto dv = v->AsRecordVal()->Lookup(0); + + if ( ! dv ) + return false; + return static_cast(dv)->canCastTo(t); } diff --git a/testing/btest/Baseline/language.type-cast-error-dynamic/output b/testing/btest/Baseline/language.type-cast-error-dynamic/output index 10d92ac199..8ebf0cc90e 100644 --- a/testing/btest/Baseline/language.type-cast-error-dynamic/output +++ b/testing/btest/Baseline/language.type-cast-error-dynamic/output @@ -1,2 +1,4 @@ -expression error in /home/robin/bro/lang-ext/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.bro, line 11: cannot cast value of type 'count' to type 'string' [a as string] -expression error in /home/robin/bro/lang-ext/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.bro, line 11: cannot cast value of type 'record { a:addr; b:port; }' to type 'string' [a as string] +expression error in /Users/jon/projects/bro/bro/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.bro, line 11: invalid cast of value with type 'count' to type 'string' [a as string] +expression error in /Users/jon/projects/bro/bro/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.bro, line 11: invalid cast of value with type 'record { a:addr; b:port; }' to type 'string' [a as string] +expression error in /Users/jon/projects/bro/bro/testing/btest/.tmp/language.type-cast-error-dynamic/type-cast-error-dynamic.bro, line 11: invalid cast of value with type 'record { data:opaque of Broker::Data; }' to type 'string' (nil $data field) [a as string] +data is string, F diff --git a/testing/btest/language/type-cast-error-dynamic.bro b/testing/btest/language/type-cast-error-dynamic.bro index 45f1d1fb5f..91fa212ce4 100644 --- a/testing/btest/language/type-cast-error-dynamic.bro +++ b/testing/btest/language/type-cast-error-dynamic.bro @@ -18,6 +18,8 @@ event bro_init() cast_to_string(42); cast_to_string(x); + cast_to_string(Broker::Data()); + print "data is string", Broker::Data() is string; }