From facbcd4cef8890ae18976fb53b67ea56b3c04454 Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Mon, 29 Jul 2024 12:08:48 +0200 Subject: [PATCH] log: Use ConstevalFormatString This changes all logging (including the wallet logging) to produce a ConstevalFormatString at compile time, so that the format string can be validated at compile-time. Also, while touching the wallet logging, avoid a copy of the template Params by using const Params&. --- src/logging.h | 6 +++--- src/wallet/scriptpubkeyman.h | 4 ++-- src/wallet/wallet.h | 4 ++-- test/lint/lint-format-strings.py | 8 -------- test/lint/run-lint-format-strings.py | 5 ----- 5 files changed, 7 insertions(+), 20 deletions(-) diff --git a/src/logging.h b/src/logging.h index 59b4f106d0..8605c8cd64 100644 --- a/src/logging.h +++ b/src/logging.h @@ -246,7 +246,7 @@ static inline bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level leve bool GetLogCategory(BCLog::LogFlags& flag, std::string_view str); template -static inline void LogPrintf_(std::string_view logging_function, std::string_view source_file, const int source_line, const BCLog::LogFlags flag, const BCLog::Level level, const char* fmt, const Args&... args) +inline void LogPrintFormatInternal(std::string_view logging_function, std::string_view source_file, const int source_line, const BCLog::LogFlags flag, const BCLog::Level level, util::ConstevalFormatString fmt, const Args&... args) { if (LogInstance().Enabled()) { std::string log_msg; @@ -254,13 +254,13 @@ static inline void LogPrintf_(std::string_view logging_function, std::string_vie log_msg = tfm::format(fmt, args...); } catch (tinyformat::format_error& fmterr) { /* Original format string will have newline so don't add one here */ - log_msg = "Error \"" + std::string(fmterr.what()) + "\" while formatting log message: " + fmt; + log_msg = "Error \"" + std::string{fmterr.what()} + "\" while formatting log message: " + fmt.fmt; } LogInstance().LogPrintStr(log_msg, logging_function, source_file, source_line, flag, level); } } -#define LogPrintLevel_(category, level, ...) LogPrintf_(__func__, __FILE__, __LINE__, category, level, __VA_ARGS__) +#define LogPrintLevel_(category, level, ...) LogPrintFormatInternal(__func__, __FILE__, __LINE__, category, level, __VA_ARGS__) // Log unconditionally. // Be conservative when using functions that unconditionally log to debug.log! diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index ba3562c638..cf7b7eaf31 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -254,9 +254,9 @@ public: /** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */ template - void WalletLogPrintf(const char* fmt, Params... parameters) const + void WalletLogPrintf(util::ConstevalFormatString wallet_fmt, const Params&... params) const { - LogPrintf(("%s " + std::string{fmt}).c_str(), m_storage.GetDisplayName(), parameters...); + LogInfo("%s %s", m_storage.GetDisplayName(), tfm::format(wallet_fmt, params...)); }; /** Watch-only address added */ diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 485eed11fa..d3a7208b15 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -927,9 +927,9 @@ public: /** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */ template - void WalletLogPrintf(const char* fmt, Params... parameters) const + void WalletLogPrintf(util::ConstevalFormatString wallet_fmt, const Params&... params) const { - LogPrintf(("%s " + std::string{fmt}).c_str(), GetDisplayName(), parameters...); + LogInfo("%s %s", GetDisplayName(), tfm::format(wallet_fmt, params...)); }; /** Upgrade the wallet */ diff --git a/test/lint/lint-format-strings.py b/test/lint/lint-format-strings.py index c30975fea7..a809851ec6 100755 --- a/test/lint/lint-format-strings.py +++ b/test/lint/lint-format-strings.py @@ -17,15 +17,7 @@ import sys FUNCTION_NAMES_AND_NUMBER_OF_LEADING_ARGUMENTS = [ 'tfm::format,1', # Assuming tfm::::format(std::ostream&, ... - 'LogError,0', - 'LogWarning,0', - 'LogInfo,0', - 'LogDebug,1', - 'LogTrace,1', - 'LogPrintf,0', - 'LogPrintLevel,2', 'strprintf,0', - 'WalletLogPrintf,0', ] RUN_LINT_FILE = 'test/lint/run-lint-format-strings.py' diff --git a/test/lint/run-lint-format-strings.py b/test/lint/run-lint-format-strings.py index a32717653a..d3c0ac92e5 100755 --- a/test/lint/run-lint-format-strings.py +++ b/test/lint/run-lint-format-strings.py @@ -15,11 +15,6 @@ import sys FALSE_POSITIVES = [ ("src/clientversion.cpp", "strprintf(_(COPYRIGHT_HOLDERS).translated, COPYRIGHT_HOLDERS_SUBSTITUTION)"), ("src/test/translation_tests.cpp", "strprintf(format, arg)"), - ("src/validationinterface.cpp", "LogDebug(BCLog::VALIDATION, fmt \"\\n\", __VA_ARGS__)"), - ("src/wallet/wallet.h", "WalletLogPrintf(const char* fmt, Params... parameters)"), - ("src/wallet/wallet.h", "LogPrintf((\"%s \" + std::string{fmt}).c_str(), GetDisplayName(), parameters...)"), - ("src/wallet/scriptpubkeyman.h", "WalletLogPrintf(const char* fmt, Params... parameters)"), - ("src/wallet/scriptpubkeyman.h", "LogPrintf((\"%s \" + std::string{fmt}).c_str(), m_storage.GetDisplayName(), parameters...)"), ]