diff --git a/.clang-tidy b/.clang-tidy index c0dba85795..348b93bdf8 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -10,4 +10,5 @@ Checks: [-*, bugprone-misplaced-widening-cast, bugprone-parent-virtual-call, bugprone-string-literal-with-embedded-nul, + bugprone-suspicious-stringview-data-usage, ] diff --git a/src/Func.cc b/src/Func.cc index b484d1ca55..6aa53eefff 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -915,7 +915,7 @@ zeek::RecordValPtr make_backtrace_element(std::string_view name, const VectorVal static auto line_location_idx = elem_type->FieldOffset("line_location"); auto elem = make_intrusive(elem_type); - elem->Assign(function_name_idx, name.data()); + elem->Assign(function_name_idx, name); elem->Assign(function_args_idx, args); if ( loc ) { diff --git a/src/MMDB.cc b/src/MMDB.cc index 406ceee513..1160409a3e 100644 --- a/src/MMDB.cc +++ b/src/MMDB.cc @@ -118,7 +118,8 @@ bool MMDB::EnsureLoaded() { if ( ! res && ! reported_error ) { reported_error = true; - zeek::emit_builtin_error(zeek::util::fmt("Failed to open %s", Description().data())); + zeek::emit_builtin_error( + zeek::util::fmt("Failed to open %.*s", static_cast(Description().size()), Description().data())); } return res; diff --git a/src/Reporter.cc b/src/Reporter.cc index 0cb93b8755..217fd277b2 100644 --- a/src/Reporter.cc +++ b/src/Reporter.cc @@ -467,7 +467,7 @@ void Reporter::Deprecation(std::string_view msg, const detail::Location* loc1, c if ( loc1 || loc2 ) PushLocation(loc1, loc2); - Warning("%s", msg.data()); + Warning("%.*s", static_cast(msg.size()), msg.data()); if ( loc1 || loc2 ) PopLocation(); diff --git a/src/Val.cc b/src/Val.cc index 451c9f6428..f98e6e708b 100644 --- a/src/Val.cc +++ b/src/Val.cc @@ -981,8 +981,8 @@ static zeek::expected BuildVal(const rapidjson::Value& j, c else if ( unit == "usec" || unit == "usecs" ) interval_secs += (value * Microseconds); else - return zeek::unexpected( - util::fmt("wrong interval format, invalid unit type %s", unit.data())); + return zeek::unexpected(util::fmt("wrong interval format, invalid unit type %.*s", + static_cast(unit.size()), unit.data())); } return make_intrusive(interval_secs, Seconds); diff --git a/src/Val.h b/src/Val.h index 6e2f4d7b60..cc606d70d5 100644 --- a/src/Val.h +++ b/src/Val.h @@ -1186,6 +1186,7 @@ public: } void Assign(int field, const char* new_val) { Assign(field, new StringVal(new_val)); } void Assign(int field, const std::string& new_val) { Assign(field, new StringVal(new_val)); } + void Assign(int field, std::string_view new_val) { Assign(field, new StringVal(new_val)); } void Assign(int field, String* new_val) { Assign(field, new StringVal(new_val)); } /** diff --git a/src/analyzer/protocol/ftp/functions.bif b/src/analyzer/protocol/ftp/functions.bif index a016a776a7..62cd318098 100644 --- a/src/analyzer/protocol/ftp/functions.bif +++ b/src/analyzer/protocol/ftp/functions.bif @@ -4,7 +4,7 @@ type ftp_port: record; %%{ #include "zeek/Reporter.h" -static zeek::RecordValPtr parse_port(std::string_view line) +static zeek::RecordValPtr parse_port(const std::string& line) { auto r = zeek::make_intrusive(zeek::BifType::Record::ftp_port); @@ -13,7 +13,7 @@ static zeek::RecordValPtr parse_port(std::string_view line) uint32_t addr = 0; int32_t bytes[6]; - if ( line.size() >= 11 && sscanf(line.data(), + if ( line.size() >= 11 && sscanf(line.c_str(), "%" SCNd32 ",%" SCNd32 ",%" SCNd32 ",%" SCNd32 ",%" SCNd32 ",%" SCNd32, &bytes[0], &bytes[1], &bytes[2], &bytes[3], &bytes[4], &bytes[5]) == 6 ) @@ -125,7 +125,7 @@ static zeek::RecordValPtr parse_eftp(const char* line) ## .. zeek:see:: parse_eftp_port parse_ftp_pasv parse_ftp_epsv fmt_ftp_port function parse_ftp_port%(s: string%): ftp_port %{ - return parse_port(s->ToStdStringView()); + return parse_port(s->ToStdString()); %} ## Converts a string representation of the FTP EPRT command (see :rfc:`2428`) @@ -181,7 +181,7 @@ function parse_ftp_pasv%(str: string%): ftp_port if ( ! line || ( line - s ) > str->Len() ) return parse_port(""); else - return parse_port(std::string_view{line}); + return parse_port(std::string{line}); %} ## Converts the result of the FTP EPSV command (see :rfc:`2428`) to an diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index c09e53e00e..dff6055e32 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -1590,7 +1590,7 @@ void Manager::ProcessMessage(std::string_view topic, broker::zeek::Event& ev) { if ( p.size() > topic.size() ) continue; - if ( strncmp(p.data(), topic.data(), p.size()) != 0 ) + if ( strncmp(p.data(), topic.data(), p.size()) != 0 ) // NOLINT(bugprone-suspicious-stringview-data-usage) continue; DBG_LOG(DBG_BROKER, "Skip processing of forwarded event: %s %s", std::string{name}.c_str(), diff --git a/src/iosource/Manager.cc b/src/iosource/Manager.cc index 5b649f667c..12e072fb27 100644 --- a/src/iosource/Manager.cc +++ b/src/iosource/Manager.cc @@ -38,7 +38,7 @@ void Manager::WakeupHandler::Ping(std::string_view where) { // Calling DBG_LOG calls fprintf, which isn't safe to call in a signal // handler. if ( signal_val != 0 ) - DBG_LOG(DBG_MAINLOOP, "Pinging WakeupHandler from %s", where.data()); + DBG_LOG(DBG_MAINLOOP, "Pinging WakeupHandler from %.*s", static_cast(where.size()), where.data()); flare.Fire(true); } diff --git a/src/storage/backend/redis/Redis.cc b/src/storage/backend/redis/Redis.cc index ace0a7645a..67d2f3ca93 100644 --- a/src/storage/backend/redis/Redis.cc +++ b/src/storage/backend/redis/Redis.cc @@ -246,7 +246,7 @@ OperationResult Redis::DoOpen(OpenResultCallback* cb, RecordValPtr options) { StringValPtr host = backend_options->GetField("server_host"); if ( host ) { PortValPtr port = backend_options->GetField("server_port"); - server_addr = util::fmt("%s:%d", host->ToStdStringView().data(), port->Port()); + server_addr = util::fmt("%s:%d", host->ToStdString().c_str(), port->Port()); REDIS_OPTIONS_SET_TCP(&opt, host->ToStdStringView().data(), port->Port()); } else { @@ -695,10 +695,12 @@ OperationResult Redis::ParseReplyError(std::string_view op_str, std::string_view if ( async_ctx->err == REDIS_ERR_TIMEOUT ) return {ReturnCode::TIMEOUT}; else if ( async_ctx->err == REDIS_ERR_IO ) - return {ReturnCode::OPERATION_FAILED, util::fmt("%s operation IO error: %s", op_str.data(), strerror(errno))}; + return {ReturnCode::OPERATION_FAILED, util::fmt("%.*s operation IO error: %s", static_cast(op_str.size()), + op_str.data(), strerror(errno))}; else return {ReturnCode::OPERATION_FAILED, - util::fmt("%s operation failed: %s", op_str.data(), reply_err_str.data())}; + util::fmt("%.*s operation failed: %.*s", static_cast(op_str.size()), op_str.data(), + static_cast(reply_err_str.size()), reply_err_str.data())}; } void Redis::DoPoll() { diff --git a/src/storage/serializer/json/JSON.cc b/src/storage/serializer/json/JSON.cc index ecc4296e37..7140aa603f 100644 --- a/src/storage/serializer/json/JSON.cc +++ b/src/storage/serializer/json/JSON.cc @@ -35,8 +35,9 @@ zeek::expected JSON::Unserialize(byte_buffer_span buf, Type std::string_view version = std::string_view(text).substr(0, semicolon); if ( version != versioned_name ) - return zeek::unexpected( - util::fmt("Version doesn't match: %s vs %s", version.data(), versioned_name.c_str())); + return zeek::unexpected(util::fmt("Version doesn't match: %.*s vs %s", + static_cast(version.size()), version.data(), + versioned_name.c_str())); return zeek::detail::ValFromJSON(text.substr(semicolon + 1), type, Func::nil); } diff --git a/src/telemetry/Manager.cc b/src/telemetry/Manager.cc index 25405c2fb2..0772879581 100644 --- a/src/telemetry/Manager.cc +++ b/src/telemetry/Manager.cc @@ -301,7 +301,8 @@ ValPtr Manager::CollectMetrics(std::string_view prefix_pattern, std::string_view // Due to the name containing the full information about a metric including a potential unit add an // asterisk to the end of the full pattern so matches work correctly. - std::string full_pattern = util::fmt("%s_%s", prefix_pattern.data(), name_pattern.data()); + std::string full_pattern = util::fmt("%.*s_%.*s", static_cast(prefix_pattern.size()), prefix_pattern.data(), + static_cast(name_pattern.size()), name_pattern.data()); if ( full_pattern[full_pattern.size() - 1] != '*' ) full_pattern.append("*"); @@ -380,7 +381,8 @@ ValPtr Manager::CollectHistogramMetrics(std::string_view prefix_pattern, std::st // Due to the name containing the full information about a metric including a potential unit add an // asterisk to the end of the full pattern so matches work correctly. - std::string full_pattern = util::fmt("%s_%s", prefix_pattern.data(), name_pattern.data()); + std::string full_pattern = util::fmt("%.*s_%.*s", static_cast(prefix_pattern.size()), prefix_pattern.data(), + static_cast(name_pattern.size()), name_pattern.data()); if ( full_pattern[full_pattern.size() - 1] != '*' ) full_pattern.append("*"); diff --git a/src/telemetry/Utils.cc b/src/telemetry/Utils.cc index f099252500..c7cca4ec84 100644 --- a/src/telemetry/Utils.cc +++ b/src/telemetry/Utils.cc @@ -16,7 +16,8 @@ std::string BuildFullPrometheusName(std::string_view prefix, std::string_view na if ( prefix.empty() || name.empty() ) reporter->FatalError("Telemetry metric families must have a non-zero-length prefix and name"); - std::string fn = util::fmt("%s_%s", prefix.data(), name.data()); + std::string fn = util::fmt("%.*s_%.*s", static_cast(prefix.size()), prefix.data(), + static_cast(name.size()), name.data()); std::for_each(fn.begin(), fn.end(), [](char& c) { if ( ! std::isalnum(c) ) c = '_';