diff --git a/CHANGES b/CHANGES index 5c6701d981..86c6aabca4 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,29 @@ +4.1.0-dev.434 | 2021-03-29 13:18:18 -0700 + + * Fix sign-compare compiler warning in coerce_to_record() (Jon Siwek, Corelight) + + * Fix maybe-uninitialized warning in ZVal::ToVal() (Jon Siwek, Corelight) + + * Change RecordVal::GetFieldAs() to use std::vector::operator[] (Jon Siwek, Corelight) + + Since the method claims it's up to the user to ensure the field exists + before calling, the extra bounds-checking done by std::vector::at() + isn't needed. + + * Add RecordVal::AssignField() and use it in supervisor code (Jon Siwek, Corelight) + + This is a convenience method to assign a known record field value by + field name. May also be useful to reduce warnings from static analysis + (e.g. Coverity) about not checking for negative return values before + assigning since that now flows through a [[noreturn]] error path. + + * GH-960: Fix include order of bundled header files (Jon Siwek, Corelight) + + Previously, a system-wide installation of any bundled auxil/ software + (like CAF) may get found/included rather than the bundled version and + possibly break the build. + 4.1.0-dev.427 | 2021-03-27 14:18:16 -0700 * Update bundled CAF to 0.18.2 (Jon Siwek, Corelight) diff --git a/VERSION b/VERSION index 39e1e04dc4..5fd68827bc 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -4.1.0-dev.427 +4.1.0-dev.434 diff --git a/src/Expr.cc b/src/Expr.cc index 5778df4235..c23fdb6b16 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3890,7 +3890,7 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, const std::vector& map) { - auto map_size = map.size(); + int map_size = map.size(); auto val = make_intrusive(rt); RecordType* val_type = val->GetType()->AsRecordType(); diff --git a/src/Val.h b/src/Val.h index 4d4984db0a..bfbca2b6a6 100644 --- a/src/Val.h +++ b/src/Val.h @@ -1152,6 +1152,19 @@ public: void Assign(int field, String* new_val) { Assign(field, new StringVal(new_val)); } + /** + * Assign a value of type @c T to a record field of the given name. + * A fatal error occurs if the no such field name exists. + */ + template + void AssignField(const char* field_name, T&& val) + { + int idx = GetType()->AsRecordType()->FieldOffset(field_name); + if ( idx < 0 ) + reporter->InternalError("missing record field: %s", field_name); + Assign(idx, std::forward(val)); + } + /** * Appends a value to the record's fields. The caller is responsible * for ensuring that fields are appended in the correct order and @@ -1288,33 +1301,33 @@ public: if constexpr ( std::is_same_v || std::is_same_v || std::is_same_v ) - return record_val->at(field).int_val; + return record_val->operator[](field).int_val; else if constexpr ( std::is_same_v ) - return record_val->at(field).uint_val; + return record_val->operator[](field).uint_val; else if constexpr ( std::is_same_v || std::is_same_v || std::is_same_v ) - return record_val->at(field).double_val; + return record_val->operator[](field).double_val; else if constexpr ( std::is_same_v ) return val_mgr->Port(record_val->at(field).uint_val); else if constexpr ( std::is_same_v ) - return record_val->at(field).string_val->Get(); + return record_val->operator[](field).string_val->Get(); else if constexpr ( std::is_same_v ) - return record_val->at(field).addr_val->Get(); + return record_val->operator[](field).addr_val->Get(); else if constexpr ( std::is_same_v ) - return record_val->at(field).subnet_val->Get(); + return record_val->operator[](field).subnet_val->Get(); else if constexpr ( std::is_same_v ) - return *(record_val->at(field).file_val); + return *(record_val->operator[](field).file_val); else if constexpr ( std::is_same_v ) - return *(record_val->at(field).func_val); + return *(record_val->operator[](field).func_val); else if constexpr ( std::is_same_v ) - return record_val->at(field).re_val->Get(); + return record_val->operator[](field).re_val->Get(); else if constexpr ( std::is_same_v ) - return record_val->at(field).record_val; + return record_val->operator[](field).record_val; else if constexpr ( std::is_same_v ) - return record_val->at(field).vector_val; + return record_val->operator[](field).vector_val; else if constexpr ( std::is_same_v ) - return record_val->at(field).table_val->Get(); + return record_val->operator[](field).table_val->Get(); else { // It's an error to reach here, although because of @@ -1329,12 +1342,12 @@ public: T GetFieldAs(int field) const { if constexpr ( std::is_integral_v && std::is_signed_v ) - return record_val->at(field).int_val; + return record_val->operator[](field).int_val; else if constexpr ( std::is_integral_v && std::is_unsigned_v ) - return record_val->at(field).uint_val; + return record_val->operator[](field).uint_val; else if constexpr ( std::is_floating_point_v ) - return record_val->at(field).double_val; + return record_val->operator[](field).double_val; // Note: we could add other types here using type traits, // such as is_same_v, etc. diff --git a/src/ZVal.cc b/src/ZVal.cc index 119d8c3f2e..0adaa70941 100644 --- a/src/ZVal.cc +++ b/src/ZVal.cc @@ -263,8 +263,9 @@ ValPtr ZVal::ToVal(const TypePtr& t) const case TYPE_TIMER: case TYPE_UNION: case TYPE_VOID: + default: v = nullptr; - reporter->InternalError("bad ret type return tag"); + reporter->InternalError("bad type in ZVal::ToVal: %s", type_name(t->Tag())); } if ( v ) diff --git a/src/supervisor/Supervisor.cc b/src/supervisor/Supervisor.cc index ce3fe8d220..d751387a1e 100644 --- a/src/supervisor/Supervisor.cc +++ b/src/supervisor/Supervisor.cc @@ -1348,22 +1348,22 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const { const auto& rt = BifType::Record::Supervisor::NodeConfig; auto rval = make_intrusive(rt); - rval->Assign(rt->FieldOffset("name"), name); + rval->AssignField("name", name); if ( interface ) - rval->Assign(rt->FieldOffset("interface"), *interface); + rval->AssignField("interface", *interface); if ( directory ) - rval->Assign(rt->FieldOffset("directory"), *directory); + rval->AssignField("directory", *directory); if ( stdout_file ) - rval->Assign(rt->FieldOffset("stdout_file"), *stdout_file); + rval->AssignField("stdout_file", *stdout_file); if ( stderr_file ) - rval->Assign(rt->FieldOffset("stderr_file"), *stderr_file); + rval->AssignField("stderr_file", *stderr_file); if ( cpu_affinity ) - rval->Assign(rt->FieldOffset("cpu_affinity"), *cpu_affinity); + rval->AssignField("cpu_affinity", *cpu_affinity); auto st = rt->GetFieldType("scripts"); auto scripts_val = make_intrusive(std::move(st)); @@ -1371,11 +1371,11 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const for ( const auto& s : scripts ) scripts_val->Assign(scripts_val->Size(), make_intrusive(s)); - rval->Assign(rt->FieldOffset("scripts"), std::move(scripts_val)); + rval->AssignField("scripts", std::move(scripts_val)); auto tt = rt->GetFieldType("cluster"); auto cluster_val = make_intrusive(std::move(tt)); - rval->Assign(rt->FieldOffset("cluster"), cluster_val); + rval->AssignField("cluster", cluster_val); for ( const auto& e : cluster ) { @@ -1385,12 +1385,12 @@ RecordValPtr Supervisor::NodeConfig::ToRecord() const const auto& ept = BifType::Record::Supervisor::ClusterEndpoint; auto val = make_intrusive(ept); - val->Assign(ept->FieldOffset("role"), BifType::Enum::Supervisor::ClusterRole->GetEnumVal(ep.role)); - val->Assign(ept->FieldOffset("host"), make_intrusive(ep.host)); - val->Assign(ept->FieldOffset("p"), val_mgr->Port(ep.port, TRANSPORT_TCP)); + val->AssignField("role", BifType::Enum::Supervisor::ClusterRole->GetEnumVal(ep.role)); + val->AssignField("host", make_intrusive(ep.host)); + val->AssignField("p", val_mgr->Port(ep.port, TRANSPORT_TCP)); if ( ep.interface ) - val->Assign(ept->FieldOffset("interface"), *ep.interface); + val->AssignField("interface", *ep.interface); cluster_val->Assign(std::move(key), std::move(val)); } @@ -1403,10 +1403,10 @@ RecordValPtr SupervisorNode::ToRecord() const const auto& rt = BifType::Record::Supervisor::NodeStatus; auto rval = make_intrusive(rt); - rval->Assign(rt->FieldOffset("node"), config.ToRecord()); + rval->AssignField("node", config.ToRecord()); if ( pid ) - rval->Assign(rt->FieldOffset("pid"), pid); + rval->AssignField("pid", pid); return rval; } @@ -1458,17 +1458,15 @@ bool SupervisedNode::InitCluster() const auto val = make_intrusive(cluster_node_type); auto node_type = supervisor_role_to_cluster_node_type(ep.role); - val->Assign(cluster_node_type->FieldOffset("node_type"), std::move(node_type)); - val->Assign(cluster_node_type->FieldOffset("ip"), make_intrusive(ep.host)); - val->Assign(cluster_node_type->FieldOffset("p"), val_mgr->Port(ep.port, TRANSPORT_TCP)); + val->AssignField("node_type", std::move(node_type)); + val->AssignField("ip", make_intrusive(ep.host)); + val->AssignField("p", val_mgr->Port(ep.port, TRANSPORT_TCP)); if ( ep.interface ) - val->Assign(cluster_node_type->FieldOffset("interface"), - *ep.interface); + val->AssignField("interface", *ep.interface); if ( manager_name && ep.role != BifEnum::Supervisor::MANAGER ) - val->Assign(cluster_node_type->FieldOffset("manager"), - *manager_name); + val->AssignField("manager", *manager_name); cluster_nodes->Assign(std::move(key), std::move(val)); } diff --git a/src/supervisor/supervisor.bif b/src/supervisor/supervisor.bif index c143bc1dcf..3d65ab31a8 100644 --- a/src/supervisor/supervisor.bif +++ b/src/supervisor/supervisor.bif @@ -86,7 +86,7 @@ function Supervisor::__node%(%): Supervisor::NodeConfig zeek::emit_builtin_error("not a supervised process"); const auto& rt = zeek::BifType::Record::Supervisor::NodeConfig; auto rval = zeek::make_intrusive(rt); - rval->Assign(rt->FieldOffset("name"), ""); + rval->AssignField("name", ""); return rval; }