diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -3075,13 +3075,15 @@ // sanitize comments per BIP-0014, format user agent and check total size for (const std::string &cmt : gArgs.GetArgs("-uacomment")) { - if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) { + const std::string sanitized = + SanitizeString(cmt, SAFE_CHARS_UA_COMMENT); + if (cmt != sanitized) { LogPrintf( "User Agent comment (%s) contains unsafe characters. " "We are going to use a sanitize version of the comment.\n", cmt); } - uacomments.push_back(cmt); + uacomments.push_back(sanitized); } std::string subversion = diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -59,6 +59,18 @@ } }; +class DummyConfigNetTest : public DummyConfig { +public: + bool SetMaxBlockSize(uint64_t maxBlockSize) override { + nMaxBlockSize = maxBlockSize; + return true; + } + uint64_t GetMaxBlockSize() const override { return nMaxBlockSize; } + +private: + uint64_t nMaxBlockSize; +}; + CDataStream AddrmanToStream(CAddrManSerializationMock &_addrman) { CDataStream ssPeersIn(SER_DISK, CLIENT_VERSION); ssPeersIn << FLATDATA(Params().DiskMagic()); @@ -185,7 +197,7 @@ } BOOST_AUTO_TEST_CASE(test_userAgentLength) { - GlobalConfig config; + DummyConfigNetTest config; config.SetMaxBlockSize(8000000); std::string long_uacomment = "very very very very very very very very very " @@ -211,4 +223,28 @@ BOOST_CHECK_EQUAL(userAgent(config), versionMessage.str()); } +BOOST_AUTO_TEST_CASE(test_userAgentSanitize) { + DummyConfigNetTest config; + + config.SetMaxBlockSize(32000000); + + gArgs.ClearMultiArg("-uacomment"); + const std::string goodua = "A valid user agent comment .,;-_?@"; + gArgs.ForceSetMultiArg("-uacomment", goodua); + std::ostringstream goodSubversion; + goodSubversion << "/Bitcoin ABC:" << CLIENT_VERSION_MAJOR << "." + << CLIENT_VERSION_MINOR << "." << CLIENT_VERSION_REVISION + << "(EB32.0; " << goodua << ")/"; + BOOST_CHECK_EQUAL(userAgent(config), goodSubversion.str()); + + gArgs.ClearMultiArg("-uacomment"); + const std::string badua = "A bad user agent comment /:()+!"; + gArgs.ForceSetMultiArg("-uacomment", badua); + std::ostringstream sanSubversion; + sanSubversion << "/Bitcoin ABC:" << CLIENT_VERSION_MAJOR << "." + << CLIENT_VERSION_MINOR << "." << CLIENT_VERSION_REVISION + << "(EB32.0; A bad user agent comment )/"; + BOOST_CHECK_EQUAL(userAgent(config), sanSubversion.str()); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/util.h b/src/util.h --- a/src/util.h +++ b/src/util.h @@ -195,6 +195,9 @@ // Remove an arg setting, used only in testing void ClearArg(const std::string &strArg); + // Remove a multi arg setting, used only in testing + void ClearMultiArg(const std::string &strArg); + private: // Munge -nofoo into -foo=0 and track the value as negated. void InterpretNegatedOption(std::string &key, std::string &val); diff --git a/src/util.cpp b/src/util.cpp --- a/src/util.cpp +++ b/src/util.cpp @@ -325,6 +325,12 @@ mapArgs.erase(strArg); } +void ArgsManager::ClearMultiArg(const std::string &strArg) { + LOCK(cs_args); + mapMultiArgs.erase(strArg); + mapArgs.erase(strArg); +} + bool HelpRequested(const ArgsManager &args) { return args.IsArgSet("-?") || args.IsArgSet("-h") || args.IsArgSet("-help"); }