diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -2805,8 +2805,10 @@ if (mapMultiArgs.count("-uacomment")) { for (const std::string &cmt : mapMultiArgs.at("-uacomment")) { if (cmt != SanitizeString(cmt, SAFE_CHARS_UA_COMMENT)) - LogPrintf("User Agent comment (%s) contains unsafe characters.", - cmt); + 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); } } @@ -2815,8 +2817,12 @@ FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, uacomments); if (subversion.size() > MAX_SUBVERSION_LENGTH) { LogPrintf("Total length of network version string (%i) exceeds maximum " - "length (%i). Reduce the number or size of uacomments.", + "length (%i). Reduce the number or size of uacomments. " + "String has been resized to the max length allowed.\n", subversion.size(), MAX_SUBVERSION_LENGTH); + subversion.resize(MAX_SUBVERSION_LENGTH - 2); + subversion.append(")/"); + LogPrintf("Current network string has been set to: %s\n", subversion); } return 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 @@ -4,12 +4,14 @@ #include "net.h" #include "addrman.h" #include "chainparams.h" +#include "config.h" #include "hash.h" #include "netbase.h" #include "serialize.h" #include "streams.h" #include "test/test_bitcoin.h" #include +#include #include class CAddrManSerializationMock : public CAddrMan { @@ -62,6 +64,11 @@ return CDataStream(vchData, SER_DISK, CLIENT_VERSION); } +bool matchString(const std::string &strValue, const std::string ®Exp) { + std::regex toMatch(regExp); + return std::regex_match(strValue, toMatch); +} + BOOST_FIXTURE_TEST_SUITE(net_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(caddrdb_read) { @@ -176,4 +183,22 @@ BOOST_CHECK_EQUAL(getSubVersionEB(0), "0.0"); } +BOOST_AUTO_TEST_CASE(test_userAgentLength) { + GlobalConfig config; + std::string long_uacomment = "very very very very very very very very very " + "very very very very very very very very very " + "very very very very very very very very very " + "very very very very very very very very very " + "very very very very very very very very very " + "very very very very very very very very very " + "very very very very very very very very very " + "very very very very very very long comment"; + ForceSetMultiArg("-uacomment", long_uacomment); + + BOOST_CHECK_EQUAL(userAgent(config).size(), MAX_SUBVERSION_LENGTH); + BOOST_CHECK(matchString(userAgent(config), + "/Bitcoin ABC:.*\\(EB[[:digit:]]+\\.[[:digit:]]; " + "very very very .*\\)/")); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/util.h b/src/util.h --- a/src/util.h +++ b/src/util.h @@ -177,6 +177,9 @@ // Forces a arg setting, used only in testing void ForceSetArg(const std::string &strArg, const std::string &strValue); +// Forces a multi arg setting, used only in testing +void ForceSetMultiArg(const std::string &strArg, const std::string &strValue); + // Remove an arg setting, used only in testing void ClearArg(const std::string &strArg); diff --git a/src/util.cpp b/src/util.cpp --- a/src/util.cpp +++ b/src/util.cpp @@ -412,6 +412,16 @@ mapArgs[strArg] = strValue; } +/** + * This function is only used for testing purpose so + * so we should not worry about element uniqueness and + * integrity of mapMultiArgs data structure + */ +void ForceSetMultiArg(const std::string &strArg, const std::string &strValue) { + LOCK(cs_args); + _mapMultiArgs[strArg].push_back(strValue); +} + void ClearArg(const std::string &strArg) { LOCK(cs_args); mapArgs.erase(strArg);