diff --git a/src/base58.cpp b/src/base58.cpp --- a/src/base58.cpp +++ b/src/base58.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -145,6 +146,9 @@ bool DecodeBase58(const std::string &str, std::vector &vchRet, int max_ret_len) { + if (!ValidAsCString(str)) { + return false; + } return DecodeBase58(str.c_str(), vchRet, max_ret_len); } @@ -178,5 +182,8 @@ bool DecodeBase58Check(const std::string &str, std::vector &vchRet, int max_ret) { + if (!ValidAsCString(str)) { + return false; + } return DecodeBase58Check(str.c_str(), vchRet, max_ret); } diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -65,6 +65,13 @@ } BOOST_CHECK(!DecodeBase58("invalid", result, 100)); + BOOST_CHECK(!DecodeBase58(std::string("invalid"), result, 100)); + BOOST_CHECK(!DecodeBase58(std::string("\0invalid", 8), result, 100)); + + BOOST_CHECK(DecodeBase58(std::string("good", 4), result, 100)); + BOOST_CHECK(!DecodeBase58(std::string("bad0IOl", 7), result, 100)); + BOOST_CHECK(!DecodeBase58(std::string("goodbad0IOl", 11), result, 100)); + BOOST_CHECK(!DecodeBase58(std::string("good\0bad0IOl", 12), result, 100)); // check that DecodeBase58 skips whitespace, but still fails with unexpected // non-whitespace at the end. @@ -73,6 +80,15 @@ std::vector expected = ParseHex("971a55"); BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end()); + + BOOST_CHECK(DecodeBase58Check(std::string("3vQB7B6MrGQZaxCuFg4oh", 21), + result, 100)); + BOOST_CHECK(!DecodeBase58Check(std::string("3vQB7B6MrGQZaxCuFg4oi", 21), + result, 100)); + BOOST_CHECK(!DecodeBase58Check(std::string("3vQB7B6MrGQZaxCuFg4oh0IOl", 25), + result, 100)); + BOOST_CHECK(!DecodeBase58Check( + std::string("3vQB7B6MrGQZaxCuFg4oh\00IOl", 26), result, 100)); } BOOST_AUTO_TEST_CASE(base58_random_encode_decode) { diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -4,6 +4,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include #include @@ -288,7 +289,7 @@ return false; } // No embedded NUL characters allowed - if (str.size() != strlen(str.c_str())) { + if (!ValidAsCString(str)) { return false; } return true; diff --git a/src/util/string.h b/src/util/string.h --- a/src/util/string.h +++ b/src/util/string.h @@ -5,6 +5,9 @@ #ifndef BITCOIN_UTIL_STRING_H #define BITCOIN_UTIL_STRING_H +#include + +#include #include #include @@ -33,4 +36,11 @@ return Join(list, separator, [](const std::string &i) { return i; }); } +/** + * Check if a string does not contain any embedded NUL (\0) characters + */ +NODISCARD inline bool ValidAsCString(const std::string &str) noexcept { + return str.size() == strlen(str.c_str()); +} + #endif // BITCOIN_UTIL_STRING_H