remove iffy reliance on type punning that relies on interpreter's behavior

This commit is contained in:
Vern Paxson 2021-03-18 08:46:18 -07:00
parent 7294bb34be
commit b473bc48e1
2 changed files with 30 additions and 7 deletions

View file

@ -127,13 +127,9 @@ function format_value(value: any) : string
if ( /^set/ in tn && strstr(tn, ",") == 0 ) if ( /^set/ in tn && strstr(tn, ",") == 0 )
{ {
# The conversion to set here is tricky and assumes local vec = Option::any_set_to_any_vec(value);
# that the set isn't indexed via a tuple of types. for ( sv in vec )
# The above check for commas in the type name part += cat(vec[sv]);
# ensures this.
local it: set[bool] = value;
for ( sv in it )
part += cat(sv);
return join_string_vec(part, ","); return join_string_vec(part, ",");
} }
else if ( /^vector/ in tn ) else if ( /^vector/ in tn )

View file

@ -213,3 +213,30 @@ function Option::set_change_handler%(ID: string, on_change: any, priority: int &
i->AddOptionHandler(func, -priority); i->AddOptionHandler(func, -priority);
return zeek::val_mgr->True(); return zeek::val_mgr->True();
%} %}
## Helper function that converts a set (of arbitrary index type) to
## a "vector of any".
##
## v: an "any" type corresponding to a set.
##
## Returns: a vector-of-any with one element for each member of v.
function Option::any_set_to_any_vec%(v: any%): any_vec
%{
auto ret_type = make_intrusive<VectorType>(base_type(TYPE_ANY));
auto ret = make_intrusive<VectorVal>(ret_type);
const auto& t = v->GetType();
if ( ! t->IsSet() )
{
zeek::emit_builtin_error("argument is not a set");
return ret;
}
auto lv = v->AsTableVal()->ToListVal();
auto n = lv->Length();
for ( int i = 0; i < n; ++i )
ret->Assign(i, lv->Idx(i));
return ret;
%}