Make our stringstream
usage locale independent.
As discussed with laanwj in #18134 (comment). Fixes #18281.
Make our stringstream
usage locale independent.
As discussed with laanwj in #18134 (comment). Fixes #18281.
1153@@ -1152,6 +1154,12 @@ TINYFORMAT_FOREACH_ARGNUM(TINYFORMAT_MAKE_FORMAT_FUNCS)
1154 template<typename... Args>
1155 std::string format(const std::string &fmt, const Args&... args)
1156 {
1157+ // Numerous tfm::format(...) callers are implicitly assuming that the output
1158+ // returned is locale independent. Notable examples include i64tostr, itostr
1159+ // and ScriptToAsmStr. Make sure to do a thorough review of all call sites
1160+ // (and other direct/indirect stringstream consumers) if this assumption is
1161+ // ever removed in the future.
1162+ assert(std::locale{} == std::locale::classic());
oss.imbue(std::locale::classic());
).
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
Reviewers, this pull request conflicts with the following ones:
If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.
1153@@ -1153,6 +1154,7 @@ template<typename... Args>
1154 std::string format(const std::string &fmt, const Args&... args)
1155 {
1156 std::ostringstream oss;
1157+ oss.imbue(std::locale::classic());
1158 format(oss, fmt.c_str(), args...);
1159 return oss.str();
How does this have any effect? This is pretty much dead code (most of our format strings are c strings, so the other function is called). Might as well remove the code here to clarify this is not the primary implementation.
0 return format(fmt.c_str(), args...);
return format(fmt.c_str(), args...);
.
243@@ -243,6 +244,7 @@ const std::string& ListBlockFilterTypes()
244 static std::once_flag flag;
245 std::call_once(flag, []() {
246 std::stringstream ret;
247+ ret.imbue(std::locale::classic());
static std::stringstream ClassicStringStream() { std::stringstream s; s.imbue(); return s; }
to our str util library, so that call sites have a lower LOC-overhead?
Would it be possible to add a
static std::stringstream ClassicStringStream() { std::stringstream s; s.imbue(); return s; }
to our str util library, so that call sites have a lower LOC-overhead?
Added! Please re-review :)
2@@ -3,12 +3,12 @@
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6-#include <wallet/db.h>
1130@@ -1126,6 +1131,7 @@ template<TINYFORMAT_ARGTYPES(n)> \
1131 std::string format(const char* fmt, TINYFORMAT_VARARGS(n)) \
1132 { \
1133 std::ostringstream oss; \
1134+ oss.imbue(std::locale::classic()); /* Added for Bitcoin Core */ \