Skip to content

Commit b448d60

Browse files
committed
tinyformat: force compile-time checks for format string literals
Callsites such as bitcoin-cli that (incorrectly) fail compile-time validation can still use tfm::format_raw.
1 parent b6a39c8 commit b448d60

File tree

5 files changed

+33
-28
lines changed

5 files changed

+33
-28
lines changed

src/bitcoin-cli.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -540,15 +540,15 @@ class NetinfoRequestHandler : public BaseRequestHandler
540540
// Report detailed peer connections list sorted by direction and minimum ping time.
541541
if (DetailsRequested() && !m_peers.empty()) {
542542
std::sort(m_peers.begin(), m_peers.end());
543-
result += strprintf("<-> type net v mping ping send recv txn blk hb %*s%*s%*s ",
544-
m_max_addr_processed_length, "addrp",
545-
m_max_addr_rate_limited_length, "addrl",
546-
m_max_age_length, "age");
543+
result += tfm::format_raw("<-> type net v mping ping send recv txn blk hb %*s%*s%*s ",
544+
m_max_addr_processed_length, "addrp",
545+
m_max_addr_rate_limited_length, "addrl",
546+
m_max_age_length, "age");
547547
if (m_is_asmap_on) result += " asmap ";
548-
result += strprintf("%*s %-*s%s\n", m_max_id_length, "id", IsAddressSelected() ? m_max_addr_length : 0, IsAddressSelected() ? "address" : "", IsVersionSelected() ? "version" : "");
548+
result += tfm::format_raw("%*s %-*s%s\n", m_max_id_length, "id", IsAddressSelected() ? m_max_addr_length : 0, IsAddressSelected() ? "address" : "", IsVersionSelected() ? "version" : "");
549549
for (const Peer& peer : m_peers) {
550550
std::string version{ToString(peer.version) + peer.sub_version};
551-
result += strprintf(
551+
result += tfm::format_raw(
552552
"%3s %6s %5s %2s%7s%7s%5s%5s%5s%5s %2s %*s%*s%*s%*i %*s %-*s%s\n",
553553
peer.is_outbound ? "out" : "in",
554554
ConnectionTypeForNetinfo(peer.conn_type),
@@ -575,7 +575,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
575575
IsAddressSelected() ? peer.addr : "",
576576
IsVersionSelected() && version != "0" ? version : "");
577577
}
578-
result += strprintf(" ms ms sec sec min min %*s\n\n", m_max_age_length, "min");
578+
result += tfm::format_raw(" ms ms sec sec min min %*s\n\n", m_max_age_length, "min");
579579
}
580580

581581
// Report peer connection totals by type.
@@ -624,7 +624,7 @@ class NetinfoRequestHandler : public BaseRequestHandler
624624
max_addr_size = std::max(addr["address"].get_str().length() + 1, max_addr_size);
625625
}
626626
for (const UniValue& addr : local_addrs) {
627-
result += strprintf("\n%-*s port %6i score %6i", max_addr_size, addr["address"].get_str(), addr["port"].getInt<int>(), addr["score"].getInt<int>());
627+
result += tfm::format_raw("\n%-*s port %6i score %6i", max_addr_size, addr["address"].get_str(), addr["port"].getInt<int>(), addr["score"].getInt<int>());
628628
}
629629
}
630630

@@ -1117,10 +1117,10 @@ static void ParseGetInfoResult(UniValue& result)
11171117
}
11181118

11191119
for (const std::string& wallet : result["balances"].getKeys()) {
1120-
result_string += strprintf("%*s %s\n",
1121-
max_balance_length,
1122-
result["balances"][wallet].getValStr(),
1123-
wallet.empty() ? "\"\"" : wallet);
1120+
result_string += tfm::format_raw("%*s %s\n",
1121+
max_balance_length,
1122+
result["balances"][wallet].getValStr(),
1123+
wallet.empty() ? "\"\"" : wallet);
11241124
}
11251125
result_string += "\n";
11261126
}

src/test/fuzz/strprintf.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
template <typename... Args>
2222
void fuzz_fmt(const std::string& fmt, const Args&... args)
2323
{
24-
(void)tfm::format(fmt.c_str(), args...);
24+
(void)tfm::format_raw(fmt.c_str(), args...);
2525
}
2626

2727
FUZZ_TARGET(str_printf)

src/test/fuzz/util/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct FuzzedWallet {
4646

4747
for (const std::string& desc_fmt : DESCS) {
4848
for (bool internal : {true, false}) {
49-
const auto descriptor{strprintf(desc_fmt.c_str(), "[5aa9973a/66h/4h/2h]" + seed_insecure, int{internal})};
49+
const auto descriptor{tfm::format_raw(desc_fmt.c_str(), "[5aa9973a/66h/4h/2h]" + seed_insecure, int{internal})};
5050

5151
FlatSigningProvider keys;
5252
std::string error;

src/tinyformat.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,33 +1056,33 @@ inline void vformat(std::ostream& out, const char* fmt, FormatListRef list)
10561056
#ifdef TINYFORMAT_USE_VARIADIC_TEMPLATES
10571057

10581058
/// Format list of arguments to the stream according to given format string.
1059-
template<typename... Args>
1060-
void format(std::ostream& out, const char* fmt, const Args&... args)
1059+
template <typename... Args>
1060+
void format_raw(std::ostream& out, const char* fmt, const Args&... args) // Renamed for Bitcoin Core
10611061
{
10621062
vformat(out, fmt, makeFormatList(args...));
10631063
}
10641064

10651065
/// Format list of arguments according to the given format string and return
10661066
/// the result as a string.
1067-
template<typename... Args>
1068-
std::string format(const char* fmt, const Args&... args)
1067+
template <typename... Args>
1068+
std::string format_raw(const char* fmt, const Args&... args) // Renamed for Bitcoin Core
10691069
{
10701070
std::ostringstream oss;
1071-
format(oss, fmt, args...);
1071+
format_raw(oss, fmt, args...);
10721072
return oss.str();
10731073
}
10741074

10751075
/// Format list of arguments to std::cout, according to the given format string
1076-
template<typename... Args>
1077-
void printf(const char* fmt, const Args&... args)
1076+
template <typename... Args>
1077+
void printf_raw(const char* fmt, const Args&... args) // Renamed for Bitcoin Core
10781078
{
1079-
format(std::cout, fmt, args...);
1079+
format_raw(std::cout, fmt, args...);
10801080
}
10811081

1082-
template<typename... Args>
1083-
void printfln(const char* fmt, const Args&... args)
1082+
template <typename... Args>
1083+
void printfln_raw(const char* fmt, const Args&... args) // Renamed for Bitcoin Core
10841084
{
1085-
format(std::cout, fmt, args...);
1085+
format_raw(std::cout, fmt, args...);
10861086
std::cout << '\n';
10871087
}
10881088

@@ -1150,7 +1150,12 @@ TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_FUNCS)
11501150
template <typename... Args>
11511151
std::string format(util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
11521152
{
1153-
return format(fmt.fmt, args...);
1153+
return format_raw(fmt.fmt, args...);
1154+
}
1155+
template <typename... Args>
1156+
void format(std::ostream& out, util::ConstevalFormatString<sizeof...(Args)> fmt, const Args&... args)
1157+
{
1158+
return format_raw(out, fmt.fmt, args...);
11541159
}
11551160
} // namespace tinyformat
11561161

src/util/translation.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ bilingual_str format(const bilingual_str& fmt, const Args&... args)
5959
return arg;
6060
}
6161
}};
62-
return bilingual_str{tfm::format(fmt.original.c_str(), translate_arg(args, false)...),
63-
tfm::format(fmt.translated.c_str(), translate_arg(args, true)...)};
62+
return bilingual_str{tfm::format_raw(fmt.original.c_str(), translate_arg(args, false)...),
63+
tfm::format_raw(fmt.translated.c_str(), translate_arg(args, true)...)};
6464
}
6565
} // namespace tinyformat
6666

0 commit comments

Comments
 (0)