Skip to content

Commit 6b51cce

Browse files
author
MarcoFalke
committed
Merge #17753: util: Don't allow Base32/64-decoding or ParseMoney(…) on strings with embedded NUL characters. Add tests.
137c80d tests: Add tests for decoding/parsing of base32, base64 and money strings containing NUL characters (practicalswift) a6fc26d util: Don't allow DecodeBase32(...) of strings with embedded NUL characters (practicalswift) 93cc18b util: Don't allow DecodeBase64(...) of strings with embedded NUL characters (practicalswift) ccc53e4 util: Don't allow ParseMoney(...) of strings with embedded NUL characters (practicalswift) Pull request description: Don't allow Base32/64-decoding or `ParseMoney(…)` on strings with embedded `NUL` characters. Add tests. Added tests before: ``` $ src/test/test_bitcoin Running 385 test cases... test/base32_tests.cpp(31): error: in "base32_tests/base32_testvectors": check failure == true has failed [false != true] test/base64_tests.cpp(31): error: in "base64_tests/base64_testvectors": check failure == true has failed [false != true] test/util_tests.cpp(1074): error: in "util_tests/util_ParseMoney": check !ParseMoney(std::string("\0-1", 3), ret) has failed test/util_tests.cpp(1076): error: in "util_tests/util_ParseMoney": check !ParseMoney(std::string("1\0", 2), ret) has failed *** 4 failures are detected in the test module "Bitcoin Core Test Suite" ``` Added tests after: ``` $ src/test/test_bitcoin Running 385 test cases... *** No errors detected ``` ACKs for top commit: laanwj: Code review ACK 137c80d Tree-SHA512: 9486a0d32b4cf686bf5a47a0778338ac571fa39c66ad6d6d6cede58ec798e87bb50a2f9b7fd79ecd1fef1ba284e4073c1b430110967073ff87bdbbde7cada447
2 parents 5e4912f + 137c80d commit 6b51cce

File tree

5 files changed

+43
-0
lines changed

5 files changed

+43
-0
lines changed

src/test/base32_tests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ BOOST_AUTO_TEST_CASE(base32_testvectors)
2020
std::string strDec = DecodeBase32(vstrOut[i]);
2121
BOOST_CHECK_EQUAL(strDec, vstrIn[i]);
2222
}
23+
24+
// Decoding strings with embedded NUL characters should fail
25+
bool failure;
26+
(void)DecodeBase32(std::string("invalid", 7), &failure);
27+
BOOST_CHECK_EQUAL(failure, true);
28+
(void)DecodeBase32(std::string("AWSX3VPP", 8), &failure);
29+
BOOST_CHECK_EQUAL(failure, false);
30+
(void)DecodeBase32(std::string("AWSX3VPP\0invalid", 16), &failure);
31+
BOOST_CHECK_EQUAL(failure, true);
32+
(void)DecodeBase32(std::string("AWSX3VPPinvalid", 15), &failure);
33+
BOOST_CHECK_EQUAL(failure, true);
2334
}
2435

2536
BOOST_AUTO_TEST_SUITE_END()

src/test/base64_tests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ BOOST_AUTO_TEST_CASE(base64_testvectors)
2020
std::string strDec = DecodeBase64(strEnc);
2121
BOOST_CHECK_EQUAL(strDec, vstrIn[i]);
2222
}
23+
24+
// Decoding strings with embedded NUL characters should fail
25+
bool failure;
26+
(void)DecodeBase64(std::string("invalid", 7), &failure);
27+
BOOST_CHECK_EQUAL(failure, true);
28+
(void)DecodeBase64(std::string("nQB/pZw=", 8), &failure);
29+
BOOST_CHECK_EQUAL(failure, false);
30+
(void)DecodeBase64(std::string("nQB/pZw=\0invalid", 16), &failure);
31+
BOOST_CHECK_EQUAL(failure, true);
32+
(void)DecodeBase64(std::string("nQB/pZw=invalid", 15), &failure);
33+
BOOST_CHECK_EQUAL(failure, true);
2334
}
2435

2536
BOOST_AUTO_TEST_SUITE_END()

src/test/util_tests.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1069,6 +1069,11 @@ BOOST_AUTO_TEST_CASE(util_ParseMoney)
10691069

10701070
// Parsing negative amounts must fail
10711071
BOOST_CHECK(!ParseMoney("-1", ret));
1072+
1073+
// Parsing strings with embedded NUL characters should fail
1074+
BOOST_CHECK(!ParseMoney(std::string("\0-1", 3), ret));
1075+
BOOST_CHECK(!ParseMoney(std::string("\01", 2), ret));
1076+
BOOST_CHECK(!ParseMoney(std::string("1\0", 2), ret));
10721077
}
10731078

10741079
BOOST_AUTO_TEST_CASE(util_IsHex)

src/util/moneystr.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
#include <tinyformat.h>
99
#include <util/strencodings.h>
10+
#include <util/string.h>
1011

1112
std::string FormatMoney(const CAmount& n)
1213
{
@@ -32,6 +33,9 @@ std::string FormatMoney(const CAmount& n)
3233

3334
bool ParseMoney(const std::string& str, CAmount& nRet)
3435
{
36+
if (!ValidAsCString(str)) {
37+
return false;
38+
}
3539
return ParseMoney(str.c_str(), nRet);
3640
}
3741

src/util/strencodings.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,12 @@ std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid)
191191

192192
std::string DecodeBase64(const std::string& str, bool* pf_invalid)
193193
{
194+
if (!ValidAsCString(str)) {
195+
if (pf_invalid) {
196+
*pf_invalid = true;
197+
}
198+
return {};
199+
}
194200
std::vector<unsigned char> vchRet = DecodeBase64(str.c_str(), pf_invalid);
195201
return std::string((const char*)vchRet.data(), vchRet.size());
196202
}
@@ -260,6 +266,12 @@ std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid)
260266

261267
std::string DecodeBase32(const std::string& str, bool* pf_invalid)
262268
{
269+
if (!ValidAsCString(str)) {
270+
if (pf_invalid) {
271+
*pf_invalid = true;
272+
}
273+
return {};
274+
}
263275
std::vector<unsigned char> vchRet = DecodeBase32(str.c_str(), pf_invalid);
264276
return std::string((const char*)vchRet.data(), vchRet.size());
265277
}

0 commit comments

Comments
 (0)