Skip to content

Commit 60a6161

Browse files
author
MarcoFalke
committed
Merge #13883: utils: Convert Windows args to utf-8 string
380c843 utils: Convert Windows args to utf-8 string (Chun Kuan Lee) Pull request description: Create a new class `WinCmdLineArgs` when building for Windows. It converts all command line arguments to utf8 string. Tree-SHA512: f098520fd123a8a452bc84a55dc8c0b88f0c475410efe57f2ccc393f86c396eed59ea1575ddc1b920323792e390fdb092061d80cdcd9b682f0ac79a22a22ff82
2 parents f504a14 + 380c843 commit 60a6161

File tree

6 files changed

+62
-1
lines changed

6 files changed

+62
-1
lines changed

src/bitcoin-cli.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <memory>
1919
#include <stdio.h>
20+
#include <tuple>
2021

2122
#include <event2/buffer.h>
2223
#include <event2/keyvalq_struct.h>
@@ -511,6 +512,10 @@ static int CommandLineRPC(int argc, char *argv[])
511512

512513
int main(int argc, char* argv[])
513514
{
515+
#ifdef WIN32
516+
util::WinCmdLineArgs winArgs;
517+
std::tie(argc, argv) = winArgs.get();
518+
#endif
514519
SetupEnvironment();
515520
if (!SetupNetworking()) {
516521
fprintf(stderr, "Error: Initializing networking failed\n");

src/bitcoind.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ static bool AppInit(int argc, char* argv[])
185185

186186
int main(int argc, char* argv[])
187187
{
188+
#ifdef WIN32
189+
util::WinCmdLineArgs winArgs;
190+
std::tie(argc, argv) = winArgs.get();
191+
#endif
188192
SetupEnvironment();
189193

190194
// Connect bitcoind signal handlers

src/qt/bitcoin.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,10 @@ static void SetupUIArgs()
552552
#ifndef BITCOIN_QT_TEST
553553
int main(int argc, char *argv[])
554554
{
555+
#ifdef WIN32
556+
util::WinCmdLineArgs winArgs;
557+
std::tie(argc, argv) = winArgs.get();
558+
#endif
555559
SetupEnvironment();
556560

557561
std::unique_ptr<interfaces::Node> node = interfaces::MakeNode();

src/util.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include <codecvt>
6262

6363
#include <io.h> /* for _commit */
64+
#include <shellapi.h>
6465
#include <shlobj.h>
6566
#endif
6667

@@ -1200,6 +1201,10 @@ void SetupEnvironment()
12001201
} catch (const std::runtime_error&) {
12011202
setenv("LC_ALL", "C", 1);
12021203
}
1204+
#elif defined(WIN32)
1205+
// Set the default input/output charset is utf-8
1206+
SetConsoleCP(CP_UTF8);
1207+
SetConsoleOutputCP(CP_UTF8);
12031208
#endif
12041209
// The path locale is lazy initialized and to avoid deinitialization errors
12051210
// in multithreading environments, it is set explicitly by the main thread.
@@ -1265,3 +1270,30 @@ int ScheduleBatchPriority()
12651270
return 1;
12661271
#endif
12671272
}
1273+
1274+
namespace util {
1275+
#ifdef WIN32
1276+
WinCmdLineArgs::WinCmdLineArgs()
1277+
{
1278+
wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
1279+
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf8_cvt;
1280+
argv = new char*[argc];
1281+
args.resize(argc);
1282+
for (int i = 0; i < argc; i++) {
1283+
args[i] = utf8_cvt.to_bytes(wargv[i]);
1284+
argv[i] = &*args[i].begin();
1285+
}
1286+
LocalFree(wargv);
1287+
}
1288+
1289+
WinCmdLineArgs::~WinCmdLineArgs()
1290+
{
1291+
delete[] argv;
1292+
}
1293+
1294+
std::pair<int, char**> WinCmdLineArgs::get()
1295+
{
1296+
return std::make_pair(argc, argv);
1297+
}
1298+
#endif
1299+
} // namespace util

src/util.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <stdint.h>
3030
#include <string>
3131
#include <unordered_set>
32+
#include <utility>
3233
#include <vector>
3334

3435
#include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
@@ -361,6 +362,21 @@ inline void insert(std::set<TsetT>& dst, const Tsrc& src) {
361362
dst.insert(src.begin(), src.end());
362363
}
363364

365+
#ifdef WIN32
366+
class WinCmdLineArgs
367+
{
368+
public:
369+
WinCmdLineArgs();
370+
~WinCmdLineArgs();
371+
std::pair<int, char**> get();
372+
373+
private:
374+
int argc;
375+
char** argv;
376+
std::vector<std::string> args;
377+
};
378+
#endif
379+
364380
} // namespace util
365381

366382
#endif // BITCOIN_UTIL_H

test/functional/feature_uacomment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ def run_test(self):
3131
self.nodes[0].assert_start_raises_init_error(["-uacomment=" + 'a' * 256], expected, match=ErrorMatch.FULL_REGEX)
3232

3333
self.log.info("test -uacomment unsafe characters")
34-
for unsafe_char in ['/', ':', '(', ')']:
34+
for unsafe_char in ['/', ':', '(', ')', '₿', '🏃']:
3535
expected = "Error: User Agent comment \(" + re.escape(unsafe_char) + "\) contains unsafe characters."
3636
self.nodes[0].assert_start_raises_init_error(["-uacomment=" + unsafe_char], expected, match=ErrorMatch.FULL_REGEX)
3737

0 commit comments

Comments
 (0)