diff --git a/scripts/base/frameworks/config/main.zeek b/scripts/base/frameworks/config/main.zeek index 5fe7f6eaaf..2d87e3c09e 100644 --- a/scripts/base/frameworks/config/main.zeek +++ b/scripts/base/frameworks/config/main.zeek @@ -127,13 +127,9 @@ function format_value(value: any) : string if ( /^set/ in tn && strstr(tn, ",") == 0 ) { - # The conversion to set here is tricky and assumes - # that the set isn't indexed via a tuple of types. - # The above check for commas in the type name - # ensures this. - local it: set[bool] = value; - for ( sv in it ) - part += cat(sv); + local vec = Option::any_set_to_any_vec(value); + for ( sv in vec ) + part += cat(vec[sv]); return join_string_vec(part, ","); } else if ( /^vector/ in tn ) diff --git a/src/option.bif b/src/option.bif index 496baae0cc..ad40ae388c 100644 --- a/src/option.bif +++ b/src/option.bif @@ -213,3 +213,30 @@ function Option::set_change_handler%(ID: string, on_change: any, priority: int & i->AddOptionHandler(func, -priority); 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(base_type(TYPE_ANY)); + auto ret = make_intrusive(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; + %}