Fix static analysis issues

This commit is contained in:
badaix 2024-12-20 21:56:12 +01:00
parent 03ce0ed2df
commit 17efc6799c
22 changed files with 56 additions and 62 deletions

View file

@ -1,30 +1,11 @@
--- ---
# Checks: '*,clang-diagnostic-*,clang-analyzer-*' Checks: 'clang-diagnostic-*,clang-analyzer-*,modernize*,performance*,readability-*size*,readability*redundant*,-readability-redundant-member-init,-readability-redundant-access-specifiers,misc*,boost-use-to-string,cert*,google-runtime-member-string-references,google-explicit-constructor,-cert-err58-cpp,-modernize-concat-nested-namespaces,-modernize-use-nodiscard,-misc-non-private-member-variables-in-classes,-modernize-use-trailing-return-type,-misc-no-recursion,-misc-const-correctness,-misc-use-anonymous-namespace'
Checks: '*,-llvmlibc-*,-readability-braces-around-statements,-hicpp-braces-around-statements,-google-readability-braces-around-statements,-hicpp-no-array-decay,-fuchsia-default-arguments-calls,-modernize-use-trailing-return-type,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-bugprone-lambda-function-name,-hicpp-signed-bitwise,-cert-err60-cpp,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-init-variables,-cppcoreguidelines-no-malloc,-hicpp-no-malloc,-google-readability-todo,-modernize-pass-by-value,-cppcoreguidelines-pro-type-member-init,-hicpp-member-init,-hicpp-avoid-c-arrays,-cppcoreguidelines-avoid-c-arrays,-modernize-avoid-c-arrays,-abseil-string-find-startswith,-google-build-using-namespace,-cppcoreguidelines-owning-memory,-readability-else-after-return,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-readability-isolate-declaration,-cert-env33-c,-abseil-*'
# Checks: '*,clang-diagnostic-*,clang-analyzer-*'
# Checks: '*,-llvmlibc-restrict-system-libc-headers,-readability-braces-around-statements,-hicpp-braces-around-statements,-google-readability-braces-around-statements,-hicpp-no-array-decay,-fuchsia-default-arguments-calls,-modernize-use-trailing-return-type,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-avoid-magic-numbers,-readability-magic-numbers,-bugprone-lambda-function-name,-hicpp-signed-bitwise,-cert-err60-cpp,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-init-variables,-cppcoreguidelines-no-malloc,-hicpp-no-malloc,-google-readability-todo,-modernize-pass-by-value,-cppcoreguidelines-pro-type-member-init,-hicpp-member-init,-hicpp-avoid-c-arrays,-cppcoreguidelines-avoid-c-arrays,-modernize-avoid-c-arrays,-abseil-string-find-startswith,-google-build-using-namespace,-cppcoreguidelines-owning-memory,-readability-else-after-return,-cppcoreguidelines-pro-type-vararg,-hicpp-vararg,-readability-isolate-declaration'
WarningsAsErrors: '' WarningsAsErrors: ''
HeaderFilterRegex: '' HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false
FormatStyle: none FormatStyle: file
User: johannes User: johannes
CheckOptions: CheckOptions:
- key: cert-dcl16-c.NewSuffixes
value: 'L;LL;LU;LLU'
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
value: '0'
- key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors
value: '1'
- key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: '1'
- key: google-readability-braces-around-statements.ShortStatementLines
value: '1'
- key: google-readability-function-size.StatementThreshold
value: '800'
- key: google-readability-namespace-comments.ShortNamespaceLines
value: '10'
- key: google-readability-namespace-comments.SpacesBeforeComments
value: '2'
- key: modernize-loop-convert.MaxCopySize - key: modernize-loop-convert.MaxCopySize
value: '16' value: '16'
- key: modernize-loop-convert.MinConfidence - key: modernize-loop-convert.MinConfidence
@ -37,5 +18,6 @@ CheckOptions:
value: llvm value: llvm
- key: modernize-use-nullptr.NullMacros - key: modernize-use-nullptr.NullMacros
value: 'NULL' value: 'NULL'
- key: hicpp-signed-bitwise.IgnorePositiveIntegerLiterals
value: '1'
... ...

7
.clangd Normal file
View file

@ -0,0 +1,7 @@
InlayHints:
Enabled: Yes
ParameterNames: No
DeducedTypes: No
Diagnostics:
UnusedIncludes: Strict
MissingIncludes: None

View file

@ -16,7 +16,7 @@ jobs:
tool: tool:
- cppcheck - cppcheck
runs-on: ubuntu-22.04 runs-on: ubuntu-24.04
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@ -43,7 +43,7 @@ jobs:
- name: configure - name: configure
run: | run: |
cmake -S . -B build \ cmake -S . -B build \
-DWERROR=ON -DBUILD_TESTS=ON \ -DWERROR=ON -DBUILD_TESTS=OFF \
-DBOOST_ROOT=boost_${BOOST_VERSION} \ -DBOOST_ROOT=boost_${BOOST_VERSION} \
-DCMAKE_BUILD_TYPE=Release \ -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE \ -DCMAKE_EXPORT_COMPILE_COMMANDS=TRUE \

View file

@ -33,6 +33,7 @@
#endif #endif
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <string>
@ -43,7 +44,7 @@ static constexpr auto LOG_TAG = "OggDecoder";
namespace decoder namespace decoder
{ {
OggDecoder::OggDecoder() : Decoder() OggDecoder::OggDecoder()
{ {
ogg_sync_init(&oy); /* Now we can read pages */ ogg_sync_init(&oy); /* Now we can read pages */
} }
@ -244,7 +245,6 @@ SampleFormat OggDecoder::setHeader(msg::CodecHeader* chunk)
if (comment.find("SAMPLE_FORMAT=") == 0) if (comment.find("SAMPLE_FORMAT=") == 0)
sampleFormat_.setFormat(comment.substr(comment.find('=') + 1)); sampleFormat_.setFormat(comment.substr(comment.find('=') + 1));
LOG(INFO, LOG_TAG) << "comment: " << comment << "\n"; LOG(INFO, LOG_TAG) << "comment: " << comment << "\n";
;
++ptr; ++ptr;
} }

View file

@ -86,7 +86,6 @@ private:
snd_pcm_uframes_t frames_; snd_pcm_uframes_t frames_;
boost::asio::posix::stream_descriptor sd_; boost::asio::posix::stream_descriptor sd_;
std::chrono::time_point<std::chrono::steady_clock> last_change_; std::chrono::time_point<std::chrono::steady_clock> last_change_;
std::recursive_mutex mutex_;
boost::asio::steady_timer timer_; boost::asio::steady_timer timer_;
std::optional<std::chrono::microseconds> buffer_time_; std::optional<std::chrono::microseconds> buffer_time_;

View file

@ -117,7 +117,7 @@ private:
template <typename T> template <typename T>
void adjustVolume(char* buffer, size_t count, double volume) void adjustVolume(char* buffer, size_t count, double volume)
{ {
T* bufferT = (T*)buffer; auto* bufferT = static_cast<T*>(buffer);
for (size_t n = 0; n < count; ++n) for (size_t n = 0; n < count; ++n)
bufferT[n] = endian::swap<T>(static_cast<T>(endian::swap<T>(bufferT[n]) * volume)); bufferT[n] = endian::swap<T>(static_cast<T>(endian::swap<T>(bufferT[n]) * volume));
} }

View file

@ -145,8 +145,8 @@ vector<PcmDevice> PulsePlayer::pcm_list(const std::string& parameter)
PulsePlayer::PulsePlayer(boost::asio::io_context& io_context, const ClientSettings::Player& settings, std::shared_ptr<Stream> stream) PulsePlayer::PulsePlayer(boost::asio::io_context& io_context, const ClientSettings::Player& settings, std::shared_ptr<Stream> stream)
: Player(io_context, settings, stream), latency_(BUFFER_TIME), pa_ml_(nullptr), pa_ctx_(nullptr), playstream_(nullptr), proplist_(nullptr), : Player(io_context, settings, stream), latency_(BUFFER_TIME), last_chunk_tick_(0), pa_ml_(nullptr), pa_ctx_(nullptr), playstream_(nullptr),
server_(std::nullopt) proplist_(nullptr), server_(std::nullopt)
{ {
auto params = utils::string::split_pairs_to_container<std::vector<std::string>>(settings.parameter, ',', '='); auto params = utils::string::split_pairs_to_container<std::vector<std::string>>(settings.parameter, ',', '=');
if (params.find("buffer_time") != params.end()) if (params.find("buffer_time") != params.end())

View file

@ -45,7 +45,14 @@ if(CMAKE_VERSION VERSION_EQUAL "3.19.0" OR CMAKE_VERSION VERSION_GREATER
"--suppress=*:${CMAKE_BINARY_DIR}/_deps/*" "--suppress=*:${CMAKE_BINARY_DIR}/_deps/*"
"--suppress=unusedFunction" "--suppress=unusedFunction"
"--suppress=noExplicitConstructor" "--suppress=noExplicitConstructor"
"--suppress=preprocessorErrorDirective") "--suppress=missingInclude"
"--suppress=missingIncludeSystem"
"--suppress=useInitializationList"
"--suppress=shadowFunction"
"--suppress=shadowVariable"
"--suppress=stlIfStrFind"
"--suppress=useStlAlgorithm"
"--suppress=virtualCallInConstructor")
if(CPPCHECK_ARGS) if(CPPCHECK_ARGS)
set(CPPCHECK_ARGS_LIST ${CPPCHECK_ARGS}) set(CPPCHECK_ARGS_LIST ${CPPCHECK_ARGS})

View file

@ -85,7 +85,7 @@ void Daemon::daemonize()
if (!group_.empty()) if (!group_.empty())
{ {
struct group* grp = getgrnam(group_.c_str()); const struct group* grp = getgrnam(group_.c_str());
if (grp == nullptr) if (grp == nullptr)
throw SnapException("no such group \"" + group_ + "\""); throw SnapException("no such group \"" + group_ + "\"");
user_gid = grp->gr_gid; user_gid = grp->gr_gid;

View file

@ -126,7 +126,8 @@ struct ErrorOr
/// @return the moved error /// @return the moved error
ErrorCode takeError() ErrorCode takeError()
{ {
return std::move(std::get<ErrorCode>(var)); auto ec = std::move(std::get<ErrorCode>(var));
return ec;
} }
private: private:

View file

@ -31,11 +31,11 @@ namespace msg
class CodecHeader : public BaseMessage class CodecHeader : public BaseMessage
{ {
public: public:
CodecHeader(const std::string& codecName = "", uint32_t size = 0) explicit CodecHeader(const std::string& codecName = "", uint32_t size = 0)
: BaseMessage(message_type::kCodecHeader), payloadSize(size), payload(nullptr), codec(codecName) : BaseMessage(message_type::kCodecHeader), payloadSize(size), payload(nullptr), codec(codecName)
{ {
if (size > 0) if (size > 0)
payload = (char*)malloc(size * sizeof(char)); payload = static_cast<char*>(malloc(size * sizeof(char)));
} }
~CodecHeader() override ~CodecHeader() override

View file

@ -116,7 +116,7 @@ struct tv
} }
/// C'tor, construct from timeval @p tv /// C'tor, construct from timeval @p tv
tv(timeval tv) : sec(tv.tv_sec), usec(tv.tv_usec){}; explicit tv(timeval tv) : sec(tv.tv_sec), usec(tv.tv_usec){};
/// C'tor, construct from @p _sec and @p _usec /// C'tor, construct from @p _sec and @p _usec
tv(int32_t _sec, int32_t _usec) : sec(_sec), usec(_usec){}; tv(int32_t _sec, int32_t _usec) : sec(_sec), usec(_usec){};
@ -173,7 +173,7 @@ struct BaseMessage
} }
/// c'tor with message type @p type_ /// c'tor with message type @p type_
BaseMessage(message_type type_) : type(type_), id(0), refersTo(0), size(0) explicit BaseMessage(message_type type_) : type(type_), id(0), refersTo(0), size(0)
{ {
} }
@ -370,7 +370,7 @@ protected:
void readVal(std::istream& stream, char** payload, uint32_t& size) const void readVal(std::istream& stream, char** payload, uint32_t& size) const
{ {
readVal(stream, size); readVal(stream, size);
*payload = (char*)realloc(*payload, size); *payload = static_cast<char*>(realloc(*payload, size));
stream.read(*payload, size); stream.read(*payload, size);
} }

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2022 Johannes Pohl Copyright (C) 2014-2024 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -83,7 +83,7 @@ public:
// logd << ", from: " << format.frameSize()*idx << ", to: " << format.frameSize()*idx + format.frameSize()*result; // logd << ", from: " << format.frameSize()*idx << ", to: " << format.frameSize()*idx + format.frameSize()*result;
if (outputBuffer != nullptr) if (outputBuffer != nullptr)
memcpy((char*)outputBuffer, (char*)(payload) + format.frameSize() * idx_, format.frameSize() * result); memcpy(static_cast<char*>(outputBuffer), static_cast<char*>(payload) + format.frameSize() * idx_, format.frameSize() * result);
idx_ += result; idx_ += result;
// logd << ", new idx: " << idx << ", result: " << result << ", wireChunk->length: " << wireChunk->length << ", format.frameSize(): " << // logd << ", new idx: " << idx << ", result: " << result << ", wireChunk->length: " << wireChunk->length << ", format.frameSize(): " <<

View file

@ -39,15 +39,15 @@ namespace msg
class WireChunk : public BaseMessage class WireChunk : public BaseMessage
{ {
public: public:
WireChunk(uint32_t size = 0) : BaseMessage(message_type::kWireChunk), payloadSize(size), payload(nullptr) explicit WireChunk(uint32_t size = 0) : BaseMessage(message_type::kWireChunk), payloadSize(size), payload(nullptr)
{ {
if (size > 0) if (size > 0)
payload = (char*)malloc(size * sizeof(char)); payload = static_cast<char*>(malloc(size * sizeof(char)));
} }
WireChunk(const WireChunk& wireChunk) : BaseMessage(message_type::kWireChunk), timestamp(wireChunk.timestamp), payloadSize(wireChunk.payloadSize) WireChunk(const WireChunk& wireChunk) : BaseMessage(message_type::kWireChunk), timestamp(wireChunk.timestamp), payloadSize(wireChunk.payloadSize)
{ {
payload = (char*)malloc(payloadSize); payload = static_cast<char*>(malloc(payloadSize));
memcpy(payload, wireChunk.payload, payloadSize); memcpy(payload, wireChunk.payload, payloadSize);
} }

View file

@ -33,7 +33,6 @@
#endif #endif
#include <filesystem> #include <filesystem>
#include <fstream>
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
@ -64,7 +63,7 @@ static void do_chown(const std::string& file_path, const std::string& user_name,
if (!user_name.empty()) if (!user_name.empty())
{ {
struct passwd* pwd = getpwnam(user_name.c_str()); const struct passwd* pwd = getpwnam(user_name.c_str());
if (pwd == nullptr) if (pwd == nullptr)
throw std::runtime_error("Failed to get uid"); throw std::runtime_error("Failed to get uid");
uid = pwd->pw_uid; uid = pwd->pw_uid;
@ -72,7 +71,7 @@ static void do_chown(const std::string& file_path, const std::string& user_name,
if (!group_name.empty()) if (!group_name.empty())
{ {
struct group* grp = getgrnam(group_name.c_str()); const struct group* grp = getgrnam(group_name.c_str());
if (grp == nullptr) if (grp == nullptr)
throw std::runtime_error("Failed to get gid"); throw std::runtime_error("Failed to get gid");
gid = grp->gr_gid; gid = grp->gr_gid;

View file

@ -75,7 +75,7 @@ std::map<std::string, T> split_pairs_to_container(const std::string& s, char pai
{ {
std::map<std::string, T> result; std::map<std::string, T> result;
auto keyValueList = split(s, pair_delim); auto keyValueList = split(s, pair_delim);
for (auto& kv : keyValueList) for (const auto& kv : keyValueList)
{ {
auto pos = kv.find(key_value_delim); auto pos = kv.find(key_value_delim);
if (pos != std::string::npos) if (pos != std::string::npos)

View file

@ -27,7 +27,6 @@
// standard headers // standard headers
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <optional>
#include <string> #include <string>

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2023 Johannes Pohl Copyright (C) 2014-2024 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -74,7 +74,7 @@ void ControlSessionWebsocket::stop()
void ControlSessionWebsocket::sendAsync(const std::string& message) void ControlSessionWebsocket::sendAsync(const std::string& message)
{ {
boost::asio::post(strand_, boost::asio::post(strand_,
[this, self = shared_from_this(), msg = message]() [this, self = shared_from_this(), msg = message]() mutable
{ {
messages_.push_back(std::move(msg)); messages_.push_back(std::move(msg));
if (messages_.size() > 1) if (messages_.size() > 1)
@ -147,7 +147,7 @@ void ControlSessionWebsocket::on_read_ws(beast::error_code ec, std::size_t bytes
if (!line.empty()) if (!line.empty())
{ {
// LOG(DEBUG, LOG_TAG) << "received: " << line << "\n"; // LOG(DEBUG, LOG_TAG) << "received: " << line << "\n";
if ((message_receiver_ != nullptr) && !line.empty()) if (message_receiver_ != nullptr)
{ {
message_receiver_->onMessageReceived(shared_from_this(), line, message_receiver_->onMessageReceived(shared_from_this(), line,
[this](const std::string& response) [this](const std::string& response)

View file

@ -25,9 +25,9 @@
#include "FLAC/stream_encoder.h" #include "FLAC/stream_encoder.h"
// standard headers // standard headers
#include <stdio.h> #include <cstdio>
#include <stdlib.h> #include <cstdlib>
#include <string.h> #include <cstring>
namespace encoder namespace encoder
{ {
@ -35,7 +35,7 @@ namespace encoder
class FlacEncoder : public Encoder class FlacEncoder : public Encoder
{ {
public: public:
FlacEncoder(const std::string& codecOptions = ""); explicit FlacEncoder(const std::string& codecOptions = "");
~FlacEncoder() override; ~FlacEncoder() override;
void encode(const msg::PcmChunk& chunk) override; void encode(const msg::PcmChunk& chunk) override;
std::string getAvailableOptions() const override; std::string getAvailableOptions() const override;

View file

@ -84,19 +84,19 @@ void OggEncoder::encode(const msg::PcmChunk& chunk)
{ {
if (sampleFormat_.sampleSize() == 1) if (sampleFormat_.sampleSize() == 1)
{ {
auto* chunkBuffer = reinterpret_cast<int8_t*>(chunk.payload); const auto* chunkBuffer = reinterpret_cast<int8_t*>(chunk.payload);
for (int i = 0; i < frames; i++) for (int i = 0; i < frames; i++)
buffer[channel][i] = chunkBuffer[sampleFormat_.channels() * i + channel] / 128.f; buffer[channel][i] = chunkBuffer[sampleFormat_.channels() * i + channel] / 128.f;
} }
else if (sampleFormat_.sampleSize() == 2) else if (sampleFormat_.sampleSize() == 2)
{ {
auto* chunkBuffer = reinterpret_cast<int16_t*>(chunk.payload); const auto* chunkBuffer = reinterpret_cast<int16_t*>(chunk.payload);
for (int i = 0; i < frames; i++) for (int i = 0; i < frames; i++)
buffer[channel][i] = chunkBuffer[sampleFormat_.channels() * i + channel] / 32768.f; buffer[channel][i] = chunkBuffer[sampleFormat_.channels() * i + channel] / 32768.f;
} }
else if (sampleFormat_.sampleSize() == 4) else if (sampleFormat_.sampleSize() == 4)
{ {
auto* chunkBuffer = reinterpret_cast<int32_t*>(chunk.payload); const auto* chunkBuffer = reinterpret_cast<int32_t*>(chunk.payload);
for (int i = 0; i < frames; i++) for (int i = 0; i < frames; i++)
buffer[channel][i] = chunkBuffer[sampleFormat_.channels() * i + channel] / 2147483648.f; buffer[channel][i] = chunkBuffer[sampleFormat_.channels() * i + channel] / 2147483648.f;
} }

View file

@ -44,7 +44,7 @@ namespace
template <typename T> template <typename T>
void assign(void* pointer, T val) void assign(void* pointer, T val)
{ {
T* p = (T*)pointer; T* p = static_cast<T*>(pointer);
*p = val; *p = val;
} }
} // namespace } // namespace
@ -246,7 +246,7 @@ void OpusEncoder::encode(const SampleFormat& format, const char* data, size_t si
if (encoded_.size() < size) if (encoded_.size() < size)
encoded_.resize(size); encoded_.resize(size);
opus_int32 len = opus_encode(enc_, (opus_int16*)data, samples_per_channel, encoded_.data(), size); opus_int32 len = opus_encode(enc_, reinterpret_cast<const opus_int16*>(data), samples_per_channel, encoded_.data(), size);
LOG(TRACE, LOG_TAG) << "Encode " << samples_per_channel << " frames, size " << size << " bytes, encoded: " << len << " bytes" << '\n'; LOG(TRACE, LOG_TAG) << "Encode " << samples_per_channel << " frames, size " << size << " bytes, encoded: " << len << " bytes" << '\n';
if (len > 0) if (len > 0)

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2021 Johannes Pohl Copyright (C) 2014-2024 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -42,7 +42,7 @@ namespace
template <typename T> template <typename T>
void assign(void* pointer, T val) void assign(void* pointer, T val)
{ {
T* p = (T*)pointer; T* p = static_cast<T*>(pointer);
*p = val; *p = val;
} }
} // namespace } // namespace