diff --git a/NEWS b/NEWS index e458562c8c..0932518fa4 100644 --- a/NEWS +++ b/NEWS @@ -202,6 +202,9 @@ Deprecated Functionality - ``RecordVal::LookupWithDefault(int)`` is deprecated, use ``RecordVal::GetFieldOrDefault(int)``. +- ``RecordVal::Lookup(const char*, bool)`` is deprecated, use either + ``RecordVal::GetField()`` or ``RecordVal::GetFieldOrDefault()``. + Zeek 3.1.0 ========== diff --git a/src/Val.cc b/src/Val.cc index f4c0f72d8b..e5d5852391 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -2781,14 +2781,24 @@ void RecordVal::DoneParsing() parse_time_records.clear(); } -IntrusivePtr RecordVal::Lookup(const char* field, bool with_default) const +const IntrusivePtr& RecordVal::GetField(const char* field) const { int idx = GetType()->AsRecordType()->FieldOffset(field); if ( idx < 0 ) reporter->InternalError("missing record field: %s", field); - return with_default ? GetFieldOrDefault(idx) : GetField(idx); + return GetField(idx); + } + +IntrusivePtr RecordVal::GetFieldOrDefault(const char* field) const + { + int idx = GetType()->AsRecordType()->FieldOffset(field); + + if ( idx < 0 ) + reporter->InternalError("missing record field: %s", field); + + return GetFieldOrDefault(idx); } IntrusivePtr RecordVal::CoerceTo(IntrusivePtr t, diff --git a/src/Val.h b/src/Val.h index 7401f9b8f3..ff8c2e1c1b 100644 --- a/src/Val.h +++ b/src/Val.h @@ -1000,6 +1000,46 @@ public: Val* LookupWithDefault(int field) const { return GetFieldOrDefault(field).release(); } + /** + * Returns the value of a given field name. + * @param field The name of a field to retrieve. + * @return The value of the given field. If no such field name exists, + * a fatal error occurs. + */ + const IntrusivePtr& GetField(const char* field) const; + + /** + * Returns the value of a given field name as cast to type @c T. + * @param field The name of a field to retrieve. + * @return The value of the given field cast to type @c T. If no such + * field name exists, a fatal error occurs. + */ + template + IntrusivePtr GetField(const char* field) const + { return cast_intrusive(GetField(field)); } + + /** + * Returns the value of a given field name if it's previously been + * assigned, or else returns the value created from evaluating the record + * fields' &default expression. + * @param field The name of a field to retrieve. + * @return The value of the given field. or the default value + * if the field hasn't been assigned yet. If no such field name exists, + * a fatal error occurs. + */ + IntrusivePtr GetFieldOrDefault(const char* field) const; + + /** + * Returns the value of a given field name or its default value + * as cast to type @c T. + * @param field The name of a field to retrieve. + * @return The value of the given field or its default value cast to + * type @c T. If no such field name exists, a fatal error occurs. + */ + template + IntrusivePtr GetFieldOrDefault(const char* field) const + { return cast_intrusive(GetField(field)); } + /** * Looks up the value of a field by field name. If the field doesn't * exist in the record type, it's an internal error: abort. @@ -1008,7 +1048,9 @@ public: * the field has yet to be initialized. * @return the value in field \a field. */ - IntrusivePtr Lookup(const char* field, bool with_default = false) const; + [[deprecated("Remove in v4.1. Use GetField() or GetFieldOrDefault().")]] + Val* Lookup(const char* field, bool with_default = false) const + { return with_default ? GetFieldOrDefault(field).release() : GetField(field).get(); } void Describe(ODesc* d) const override; diff --git a/src/analyzer/protocol/conn-size/ConnSize.cc b/src/analyzer/protocol/conn-size/ConnSize.cc index e7682111b2..28f9a95c52 100644 --- a/src/analyzer/protocol/conn-size/ConnSize.cc +++ b/src/analyzer/protocol/conn-size/ConnSize.cc @@ -170,8 +170,8 @@ void ConnSize_Analyzer::SetDurationThreshold(double duration) void ConnSize_Analyzer::UpdateConnVal(RecordVal *conn_val) { // RecordType *connection_type is decleared in NetVar.h - RecordVal *orig_endp = conn_val->Lookup("orig")->AsRecordVal(); - RecordVal *resp_endp = conn_val->Lookup("resp")->AsRecordVal(); + RecordVal* orig_endp = conn_val->GetField("orig")->AsRecordVal(); + RecordVal* resp_endp = conn_val->GetField("resp")->AsRecordVal(); // endpoint is the RecordType from NetVar.h int pktidx = zeek::id::endpoint->FieldOffset("num_pkts"); diff --git a/src/analyzer/protocol/icmp/ICMP.cc b/src/analyzer/protocol/icmp/ICMP.cc index 0a0eb3f1b8..664a5a8cdd 100644 --- a/src/analyzer/protocol/icmp/ICMP.cc +++ b/src/analyzer/protocol/icmp/ICMP.cc @@ -459,22 +459,22 @@ void ICMP_Analyzer::Describe(ODesc* d) const void ICMP_Analyzer::UpdateConnVal(RecordVal *conn_val) { - auto orig_endp = conn_val->Lookup("orig"); - auto resp_endp = conn_val->Lookup("resp"); + const auto& orig_endp = conn_val->GetField("orig"); + const auto& resp_endp = conn_val->GetField("resp"); - UpdateEndpointVal(&orig_endp, true); - UpdateEndpointVal(&resp_endp, false); + UpdateEndpointVal(orig_endp, true); + UpdateEndpointVal(resp_endp, false); // Call children's UpdateConnVal Analyzer::UpdateConnVal(conn_val); } -void ICMP_Analyzer::UpdateEndpointVal(IntrusivePtr* endp_arg, bool is_orig) +void ICMP_Analyzer::UpdateEndpointVal(const IntrusivePtr& endp_arg, bool is_orig) { Conn()->EnableStatusUpdateTimer(); int size = is_orig ? request_len : reply_len; - auto endp = (*endp_arg)->AsRecordVal(); + auto endp = endp_arg->AsRecordVal(); if ( size < 0 ) { diff --git a/src/analyzer/protocol/icmp/ICMP.h b/src/analyzer/protocol/icmp/ICMP.h index 3a91b26a5f..74ecb3a322 100644 --- a/src/analyzer/protocol/icmp/ICMP.h +++ b/src/analyzer/protocol/icmp/ICMP.h @@ -84,7 +84,7 @@ protected: RuleMatcherState matcher_state; private: - void UpdateEndpointVal(IntrusivePtr* endp, bool is_orig); + void UpdateEndpointVal(const IntrusivePtr& endp, bool is_orig); }; // Returns the counterpart type to the given type (e.g., the counterpart diff --git a/src/analyzer/protocol/tcp/TCP.cc b/src/analyzer/protocol/tcp/TCP.cc index 85ef4f4a0d..27d8235483 100644 --- a/src/analyzer/protocol/tcp/TCP.cc +++ b/src/analyzer/protocol/tcp/TCP.cc @@ -1287,8 +1287,8 @@ void TCP_Analyzer::FlipRoles() void TCP_Analyzer::UpdateConnVal(RecordVal *conn_val) { - RecordVal *orig_endp_val = conn_val->Lookup("orig")->AsRecordVal(); - RecordVal *resp_endp_val = conn_val->Lookup("resp")->AsRecordVal(); + RecordVal* orig_endp_val = conn_val->GetField("orig")->AsRecordVal(); + RecordVal* resp_endp_val = conn_val->GetField("resp")->AsRecordVal(); orig_endp_val->Assign(0, val_mgr->Count(orig->Size())); orig_endp_val->Assign(1, val_mgr->Count(int(orig->state))); diff --git a/src/analyzer/protocol/udp/UDP.cc b/src/analyzer/protocol/udp/UDP.cc index a68cd531ab..9965d3439d 100644 --- a/src/analyzer/protocol/udp/UDP.cc +++ b/src/analyzer/protocol/udp/UDP.cc @@ -216,8 +216,8 @@ void UDP_Analyzer::DeliverPacket(int len, const u_char* data, bool is_orig, void UDP_Analyzer::UpdateConnVal(RecordVal *conn_val) { - RecordVal *orig_endp = conn_val->Lookup("orig")->AsRecordVal(); - RecordVal *resp_endp = conn_val->Lookup("resp")->AsRecordVal(); + RecordVal* orig_endp = conn_val->GetField("orig")->AsRecordVal(); + RecordVal* resp_endp = conn_val->GetField("resp")->AsRecordVal(); UpdateEndpointVal(orig_endp, true); UpdateEndpointVal(resp_endp, false); diff --git a/src/file_analysis/analyzer/data_event/DataEvent.cc b/src/file_analysis/analyzer/data_event/DataEvent.cc index df3f31348b..082618c4ec 100644 --- a/src/file_analysis/analyzer/data_event/DataEvent.cc +++ b/src/file_analysis/analyzer/data_event/DataEvent.cc @@ -21,8 +21,8 @@ DataEvent::DataEvent(RecordVal* args, File* file, file_analysis::Analyzer* DataEvent::Instantiate(RecordVal* args, File* file) { - auto chunk_val = args->Lookup("chunk_event"); - auto stream_val = args->Lookup("stream_event"); + const auto& chunk_val = args->GetField("chunk_event"); + const auto& stream_val = args->GetField("stream_event"); if ( ! chunk_val && ! stream_val ) return nullptr; diff --git a/src/file_analysis/analyzer/extract/Extract.cc b/src/file_analysis/analyzer/extract/Extract.cc index aa0ba1cbca..68daecab1f 100644 --- a/src/file_analysis/analyzer/extract/Extract.cc +++ b/src/file_analysis/analyzer/extract/Extract.cc @@ -32,9 +32,9 @@ Extract::~Extract() safe_close(fd); } -static IntrusivePtr get_extract_field_val(RecordVal* args, const char* name) +static const IntrusivePtr& get_extract_field_val(RecordVal* args, const char* name) { - auto rval = args->Lookup(name); + const auto& rval = args->GetField(name); if ( ! rval ) reporter->Error("File extraction analyzer missing arg field: %s", name); @@ -44,8 +44,8 @@ static IntrusivePtr get_extract_field_val(RecordVal* args, const char* name file_analysis::Analyzer* Extract::Instantiate(RecordVal* args, File* file) { - auto fname = get_extract_field_val(args, "extract_filename"); - auto limit = get_extract_field_val(args, "extract_limit"); + const auto& fname = get_extract_field_val(args, "extract_filename"); + const auto& limit = get_extract_field_val(args, "extract_limit"); if ( ! fname || ! limit ) return nullptr; diff --git a/src/file_analysis/analyzer/x509/OCSP.cc b/src/file_analysis/analyzer/x509/OCSP.cc index 5bd8a8a3c3..f2dd74883b 100644 --- a/src/file_analysis/analyzer/x509/OCSP.cc +++ b/src/file_analysis/analyzer/x509/OCSP.cc @@ -32,16 +32,6 @@ using namespace file_analysis; #define OCSP_STRING_BUF_SIZE 2048 -static IntrusivePtr get_ocsp_type(RecordVal* args, const char* name) - { - auto rval = args->Lookup(name); - - if ( ! rval ) - reporter->Error("File extraction analyzer missing arg field: %s", name); - - return rval; - } - static bool OCSP_RESPID_bio(OCSP_BASICRESP* basic_resp, BIO* bio) { #if ( OPENSSL_VERSION_NUMBER < 0x10100000L ) || defined(LIBRESSL_VERSION_NUMBER) diff --git a/src/input/Manager.cc b/src/input/Manager.cc index d72d56a8b9..fcdb688087 100644 --- a/src/input/Manager.cc +++ b/src/input/Manager.cc @@ -233,7 +233,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) return false; } - string name = description->Lookup("name", true)->AsString()->CheckString(); + string name = description->GetFieldOrDefault("name")->AsString()->CheckString(); if ( Stream *i = FindStream(name) ) { @@ -242,17 +242,19 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) return false; } - auto reader = description->Lookup("reader", true); + auto reader = description->GetFieldOrDefault("reader"); // get the source ... - const BroString* bsource = description->Lookup("source", true)->AsString(); + auto source_val = description->GetFieldOrDefault("source"); + const BroString* bsource = source_val->AsString(); string source((const char*) bsource->Bytes(), bsource->Len()); ReaderBackend::ReaderInfo rinfo; rinfo.source = copy_string(source.c_str()); rinfo.name = copy_string(name.c_str()); - auto mode = description->Lookup("mode", true)->AsEnumVal(); + auto mode_val = description->GetFieldOrDefault("mode"); + auto mode = mode_val->AsEnumVal(); switch ( mode->InternalInt() ) { case 0: @@ -272,7 +274,7 @@ bool Manager::CreateStream(Stream* info, RecordVal* description) return false; } - auto config = description->Lookup("config", true); + auto config = description->GetFieldOrDefault("config"); info->config = config.release()->AsTableVal(); { @@ -317,14 +319,15 @@ bool Manager::CreateEventStream(RecordVal* fval) return false; } - string stream_name = fval->Lookup("name", true)->AsString()->CheckString(); + string stream_name = fval->GetFieldOrDefault("name")->AsString()->CheckString(); - auto fields_val = fval->Lookup("fields", true); + auto fields_val = fval->GetFieldOrDefault("fields"); RecordType* fields = fields_val->AsType()->AsTypeType()->Type()->AsRecordType(); - auto want_record = fval->Lookup("want_record", true); + auto want_record = fval->GetFieldOrDefault("want_record"); - Func* event = fval->Lookup("ev", true)->AsFunc(); + auto ev_val = fval->GetFieldOrDefault("ev"); + Func* event = ev_val->AsFunc(); const auto& etype = event->GetType(); @@ -412,7 +415,7 @@ bool Manager::CreateEventStream(RecordVal* fval) else assert(false); - auto error_event_val = fval->Lookup("error_ev", true); + auto error_event_val = fval->GetFieldOrDefault("error_ev"); Func* error_event = error_event_val ? error_event_val->AsFunc() : nullptr; if ( ! CheckErrorEventTypes(stream_name, error_event, false) ) @@ -470,19 +473,19 @@ bool Manager::CreateTableStream(RecordVal* fval) return false; } - string stream_name = fval->Lookup("name", true)->AsString()->CheckString(); + string stream_name = fval->GetFieldOrDefault("name")->AsString()->CheckString(); - auto pred = fval->Lookup("pred", true); - auto idx_val = fval->Lookup("idx", true); + auto pred = fval->GetFieldOrDefault("pred"); + auto idx_val = fval->GetFieldOrDefault("idx"); RecordType* idx = idx_val->AsType()->AsTypeType()->Type()->AsRecordType(); IntrusivePtr val; - auto val_val = fval->Lookup("val", true); + auto val_val = fval->GetFieldOrDefault("val"); if ( val_val ) val = {NewRef{}, val_val->AsType()->AsTypeType()->Type()->AsRecordType()}; - auto dst = fval->Lookup("destination", true); + auto dst = fval->GetFieldOrDefault("destination"); // check if index fields match table description int num = idx->NumFields(); @@ -518,7 +521,7 @@ bool Manager::CreateTableStream(RecordVal* fval) return false; } - auto want_record = fval->Lookup("want_record", true); + auto want_record = fval->GetFieldOrDefault("want_record"); if ( val ) { @@ -551,7 +554,7 @@ bool Manager::CreateTableStream(RecordVal* fval) } } - auto event_val = fval->Lookup("ev", true); + auto event_val = fval->GetFieldOrDefault("ev"); Func* event = event_val ? event_val->AsFunc() : nullptr; if ( event ) @@ -624,7 +627,7 @@ bool Manager::CreateTableStream(RecordVal* fval) assert(want_record->InternalInt() == 1 || want_record->InternalInt() == 0); } - auto error_event_val = fval->Lookup("error_ev", true); + auto error_event_val = fval->GetFieldOrDefault("error_ev"); Func* error_event = error_event_val ? error_event_val->AsFunc() : nullptr; if ( ! CheckErrorEventTypes(stream_name, error_event, true) ) diff --git a/src/logging/Manager.cc b/src/logging/Manager.cc index d13c62fcb3..2e798273ae 100644 --- a/src/logging/Manager.cc +++ b/src/logging/Manager.cc @@ -237,7 +237,7 @@ bool Manager::CreateStream(EnumVal* id, RecordVal* sval) return false; } - RecordType* columns = sval->Lookup("columns") + RecordType* columns = sval->GetField("columns") ->AsType()->AsTypeType()->Type()->AsRecordType(); bool log_attr_present = false; @@ -264,7 +264,7 @@ bool Manager::CreateStream(EnumVal* id, RecordVal* sval) return false; } - auto event_val = sval->Lookup("ev"); + const auto& event_val = sval->GetField("ev"); Func* event = event_val ? event_val->AsFunc() : nullptr; if ( event ) @@ -545,22 +545,22 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval) return false; // Find the right writer type. - EnumVal* writer = fval->Lookup("writer", true)->AsEnumVal(); + auto writer = fval->GetFieldOrDefault("writer"); // Create a new Filter instance. - auto name = fval->Lookup("name", true); - auto pred = fval->Lookup("pred", true); - auto path_func = fval->Lookup("path_func", true); - auto log_local = fval->Lookup("log_local", true); - auto log_remote = fval->Lookup("log_remote", true); - auto interv = fval->Lookup("interv", true); - auto postprocessor = fval->Lookup("postprocessor", true); - auto config = fval->Lookup("config", true); - auto field_name_map = fval->Lookup("field_name_map", true); - auto scope_sep = fval->Lookup("scope_sep", true); - auto ext_prefix = fval->Lookup("ext_prefix", true); - auto ext_func = fval->Lookup("ext_func", true); + auto name = fval->GetFieldOrDefault("name"); + auto pred = fval->GetFieldOrDefault("pred"); + auto path_func = fval->GetFieldOrDefault("path_func"); + auto log_local = fval->GetFieldOrDefault("log_local"); + auto log_remote = fval->GetFieldOrDefault("log_remote"); + auto interv = fval->GetFieldOrDefault("interv"); + auto postprocessor = fval->GetFieldOrDefault("postprocessor"); + auto config = fval->GetFieldOrDefault("config"); + auto field_name_map = fval->GetFieldOrDefault("field_name_map"); + auto scope_sep = fval->GetFieldOrDefault("scope_sep"); + auto ext_prefix = fval->GetFieldOrDefault("ext_prefix"); + auto ext_func = fval->GetFieldOrDefault("ext_func"); Filter* filter = new Filter; filter->fval = fval->Ref(); @@ -581,8 +581,8 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval) // Build the list of fields that the filter wants included, including // potentially rolling out fields. - auto include = fval->Lookup("include"); - auto exclude = fval->Lookup("exclude"); + const auto& include = fval->GetField("include"); + const auto& exclude = fval->GetField("exclude"); filter->num_ext_fields = 0; if ( filter->ext_func ) @@ -616,7 +616,7 @@ bool Manager::AddFilter(EnumVal* id, RecordVal* fval) } // Get the path for the filter. - auto path_val = fval->Lookup("path"); + auto path_val = fval->GetField("path"); if ( path_val ) { diff --git a/src/supervisor/Supervisor.cc b/src/supervisor/Supervisor.cc index ea76fd0a94..c02dc6ca5f 100644 --- a/src/supervisor/Supervisor.cc +++ b/src/supervisor/Supervisor.cc @@ -982,33 +982,33 @@ static BifEnum::Supervisor::ClusterRole role_str_to_enum(std::string_view r) Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node) { Supervisor::NodeConfig rval; - rval.name = node->Lookup("name")->AsString()->CheckString(); - auto iface_val = node->Lookup("interface"); + rval.name = node->GetField("name")->AsString()->CheckString(); + const auto& iface_val = node->GetField("interface"); if ( iface_val ) rval.interface = iface_val->AsString()->CheckString(); - auto directory_val = node->Lookup("directory"); + const auto& directory_val = node->GetField("directory"); if ( directory_val ) rval.directory = directory_val->AsString()->CheckString(); - auto stdout_val = node->Lookup("stdout_file"); + const auto& stdout_val = node->GetField("stdout_file"); if ( stdout_val ) rval.stdout_file = stdout_val->AsString()->CheckString(); - auto stderr_val = node->Lookup("stderr_file"); + const auto& stderr_val = node->GetField("stderr_file"); if ( stderr_val ) rval.stderr_file = stderr_val->AsString()->CheckString(); - auto affinity_val = node->Lookup("cpu_affinity"); + const auto& affinity_val = node->GetField("cpu_affinity"); if ( affinity_val ) rval.cpu_affinity = affinity_val->AsInt(); - auto scripts_val = node->Lookup("scripts")->AsVectorVal(); + auto scripts_val = node->GetField("scripts")->AsVectorVal(); for ( auto i = 0u; i < scripts_val->Size(); ++i ) { @@ -1016,7 +1016,7 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node) rval.scripts.emplace_back(std::move(script)); } - auto cluster_table_val = node->Lookup("cluster")->AsTableVal(); + auto cluster_table_val = node->GetField("cluster")->AsTableVal(); auto cluster_table = cluster_table_val->AsTable(); auto c = cluster_table->InitForIteration(); HashKey* k; @@ -1030,11 +1030,11 @@ Supervisor::NodeConfig Supervisor::NodeConfig::FromRecord(const RecordVal* node) auto rv = v->GetVal()->AsRecordVal(); Supervisor::ClusterEndpoint ep; - ep.role = static_cast(rv->Lookup("role")->AsEnum()); - ep.host = rv->Lookup("host")->AsAddr().AsString(); - ep.port = rv->Lookup("p")->AsPortVal()->Port(); + ep.role = static_cast(rv->GetField("role")->AsEnum()); + ep.host = rv->GetField("host")->AsAddr().AsString(); + ep.port = rv->GetField("p")->AsPortVal()->Port(); - auto iface = rv->Lookup("interface"); + const auto& iface = rv->GetField("interface"); if ( iface ) ep.interface = iface->AsStringVal()->ToStdString();