Fix bech32::Encode() error handling

Previously, an input with invalid characters would result in out-of-bounds
reads, potentially exposing up to 224 bytes of memory following the location of
the CHARSET constant. This commit fixes the function to return an empty string,
which is what was originally documented as happening.
This commit is contained in:
Jack Grigg 2018-06-07 15:30:44 +12:00
parent 6a2cc8ddc0
commit c8511dfc07
No known key found for this signature in database
GPG Key ID: 1B8D649257DB0829
2 changed files with 36 additions and 0 deletions

View File

@ -150,6 +150,9 @@ std::string Encode(const std::string& hrp, const data& values) {
std::string ret = hrp + '1';
ret.reserve(ret.size() + combined.size());
for (auto c : combined) {
if (c >= 32) {
return "";
}
ret += CHARSET[c];
}
return ret;

View File

@ -64,4 +64,37 @@ BOOST_AUTO_TEST_CASE(bip173_testvectors_invalid)
}
}
BOOST_AUTO_TEST_CASE(bech32_deterministic_valid)
{
for (size_t i = 0; i < 255; i++) {
std::vector<unsigned char> input(32, i);
auto encoded = bech32::Encode("a", input);
if (i < 32) {
// Valid input
BOOST_CHECK(!encoded.empty());
auto ret = bech32::Decode(encoded);
BOOST_CHECK(ret.first == "a");
BOOST_CHECK(ret.second == input);
} else {
// Invalid input
BOOST_CHECK(encoded.empty());
}
}
for (size_t i = 0; i < 255; i++) {
std::vector<unsigned char> input(43, i);
auto encoded = bech32::Encode("a", input);
if (i < 32) {
// Valid input
BOOST_CHECK(!encoded.empty());
auto ret = bech32::Decode(encoded);
BOOST_CHECK(ret.first == "a");
BOOST_CHECK(ret.second == input);
} else {
// Invalid input
BOOST_CHECK(encoded.empty());
}
}
}
BOOST_AUTO_TEST_SUITE_END()