aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/release-notes/release-notes-0.17.0.md2
-rw-r--r--src/bench/checkblock.cpp4
-rw-r--r--src/bitcoin-cli.cpp5
-rw-r--r--src/bitcoind.cpp4
-rw-r--r--src/qt/bitcoin.cpp4
-rw-r--r--src/test/script_tests.cpp8
-rw-r--r--src/util.cpp32
-rw-r--r--src/util.h16
-rwxr-xr-xtest/functional/feature_uacomment.py2
9 files changed, 69 insertions, 8 deletions
diff --git a/doc/release-notes/release-notes-0.17.0.md b/doc/release-notes/release-notes-0.17.0.md
index ce7a1f6ac1..418d7ba5f9 100644
--- a/doc/release-notes/release-notes-0.17.0.md
+++ b/doc/release-notes/release-notes-0.17.0.md
@@ -270,7 +270,7 @@ Low-level RPC changes
- The new RPC `scantxoutset` can be used to scan the UTXO set for entries
that match certain output descriptors. Refer to the [output descriptors
- reference documentation](doc/descriptors.md) for more details. This call
+ reference documentation](/doc/descriptors.md) for more details. This call
is similar to `listunspent` but does not use a wallet, meaning that the
wallet can be disabled at compile or run time. This call is experimental,
as such, is subject to changes or removal in future releases.
diff --git a/src/bench/checkblock.cpp b/src/bench/checkblock.cpp
index 6f03581c4b..e325333c01 100644
--- a/src/bench/checkblock.cpp
+++ b/src/bench/checkblock.cpp
@@ -20,7 +20,7 @@ namespace block_bench {
static void DeserializeBlockTest(benchmark::State& state)
{
CDataStream stream((const char*)block_bench::block413567,
- (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
+ (const char*)block_bench::block413567 + sizeof(block_bench::block413567),
SER_NETWORK, PROTOCOL_VERSION);
char a = '\0';
stream.write(&a, 1); // Prevent compaction
@@ -36,7 +36,7 @@ static void DeserializeBlockTest(benchmark::State& state)
static void DeserializeAndCheckBlockTest(benchmark::State& state)
{
CDataStream stream((const char*)block_bench::block413567,
- (const char*)&block_bench::block413567[sizeof(block_bench::block413567)],
+ (const char*)block_bench::block413567 + sizeof(block_bench::block413567),
SER_NETWORK, PROTOCOL_VERSION);
char a = '\0';
stream.write(&a, 1); // Prevent compaction
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 09507fd249..f466505114 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -17,6 +17,7 @@
#include <memory>
#include <stdio.h>
+#include <tuple>
#include <event2/buffer.h>
#include <event2/keyvalq_struct.h>
@@ -511,6 +512,10 @@ static int CommandLineRPC(int argc, char *argv[])
int main(int argc, char* argv[])
{
+#ifdef WIN32
+ util::WinCmdLineArgs winArgs;
+ std::tie(argc, argv) = winArgs.get();
+#endif
SetupEnvironment();
if (!SetupNetworking()) {
fprintf(stderr, "Error: Initializing networking failed\n");
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index bf04d95b50..18fcd9bc2a 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -185,6 +185,10 @@ static bool AppInit(int argc, char* argv[])
int main(int argc, char* argv[])
{
+#ifdef WIN32
+ util::WinCmdLineArgs winArgs;
+ std::tie(argc, argv) = winArgs.get();
+#endif
SetupEnvironment();
// Connect bitcoind signal handlers
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index 1e950e2686..61a9f390e9 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -552,6 +552,10 @@ static void SetupUIArgs()
#ifndef BITCOIN_QT_TEST
int main(int argc, char *argv[])
{
+#ifdef WIN32
+ util::WinCmdLineArgs winArgs;
+ std::tie(argc, argv) = winArgs.get();
+#endif
SetupEnvironment();
std::unique_ptr<interfaces::Node> node = interfaces::MakeNode();
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 67c377778f..7fbf37e7fb 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -1013,21 +1013,21 @@ BOOST_AUTO_TEST_CASE(script_PushData)
ScriptError err;
std::vector<std::vector<unsigned char> > directStack;
- BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
+ BOOST_CHECK(EvalScript(directStack, CScript(direct, direct + sizeof(direct)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
std::vector<std::vector<unsigned char> > pushdata1Stack;
- BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
+ BOOST_CHECK(EvalScript(pushdata1Stack, CScript(pushdata1, pushdata1 + sizeof(pushdata1)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK(pushdata1Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
std::vector<std::vector<unsigned char> > pushdata2Stack;
- BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
+ BOOST_CHECK(EvalScript(pushdata2Stack, CScript(pushdata2, pushdata2 + sizeof(pushdata2)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK(pushdata2Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
std::vector<std::vector<unsigned char> > pushdata4Stack;
- BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
+ BOOST_CHECK(EvalScript(pushdata4Stack, CScript(pushdata4, pushdata4 + sizeof(pushdata4)), SCRIPT_VERIFY_P2SH, BaseSignatureChecker(), SigVersion::BASE, &err));
BOOST_CHECK(pushdata4Stack == directStack);
BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err));
}
diff --git a/src/util.cpp b/src/util.cpp
index fa624aee90..1002302904 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -61,6 +61,7 @@
#include <codecvt>
#include <io.h> /* for _commit */
+#include <shellapi.h>
#include <shlobj.h>
#endif
@@ -1200,6 +1201,10 @@ void SetupEnvironment()
} catch (const std::runtime_error&) {
setenv("LC_ALL", "C", 1);
}
+#elif defined(WIN32)
+ // Set the default input/output charset is utf-8
+ SetConsoleCP(CP_UTF8);
+ SetConsoleOutputCP(CP_UTF8);
#endif
// The path locale is lazy initialized and to avoid deinitialization errors
// in multithreading environments, it is set explicitly by the main thread.
@@ -1265,3 +1270,30 @@ int ScheduleBatchPriority()
return 1;
#endif
}
+
+namespace util {
+#ifdef WIN32
+WinCmdLineArgs::WinCmdLineArgs()
+{
+ wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc);
+ std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> utf8_cvt;
+ argv = new char*[argc];
+ args.resize(argc);
+ for (int i = 0; i < argc; i++) {
+ args[i] = utf8_cvt.to_bytes(wargv[i]);
+ argv[i] = &*args[i].begin();
+ }
+ LocalFree(wargv);
+}
+
+WinCmdLineArgs::~WinCmdLineArgs()
+{
+ delete[] argv;
+}
+
+std::pair<int, char**> WinCmdLineArgs::get()
+{
+ return std::make_pair(argc, argv);
+}
+#endif
+} // namespace util
diff --git a/src/util.h b/src/util.h
index f119385e48..fa6d2cd489 100644
--- a/src/util.h
+++ b/src/util.h
@@ -29,6 +29,7 @@
#include <stdint.h>
#include <string>
#include <unordered_set>
+#include <utility>
#include <vector>
#include <boost/thread/condition_variable.hpp> // for boost::thread_interrupted
@@ -361,6 +362,21 @@ inline void insert(std::set<TsetT>& dst, const Tsrc& src) {
dst.insert(src.begin(), src.end());
}
+#ifdef WIN32
+class WinCmdLineArgs
+{
+public:
+ WinCmdLineArgs();
+ ~WinCmdLineArgs();
+ std::pair<int, char**> get();
+
+private:
+ int argc;
+ char** argv;
+ std::vector<std::string> args;
+};
+#endif
+
} // namespace util
#endif // BITCOIN_UTIL_H
diff --git a/test/functional/feature_uacomment.py b/test/functional/feature_uacomment.py
index 691a39b825..fb4ad21359 100755
--- a/test/functional/feature_uacomment.py
+++ b/test/functional/feature_uacomment.py
@@ -31,7 +31,7 @@ class UacommentTest(BitcoinTestFramework):
self.nodes[0].assert_start_raises_init_error(["-uacomment=" + 'a' * 256], expected, match=ErrorMatch.FULL_REGEX)
self.log.info("test -uacomment unsafe characters")
- for unsafe_char in ['/', ':', '(', ')']:
+ for unsafe_char in ['/', ':', '(', ')', '₿', '🏃']:
expected = "Error: User Agent comment \(" + re.escape(unsafe_char) + "\) contains unsafe characters."
self.nodes[0].assert_start_raises_init_error(["-uacomment=" + unsafe_char], expected, match=ErrorMatch.FULL_REGEX)