Browse Source

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.
pull/4/head
Jack Grigg 6 years ago
parent
commit
c8511dfc07
No known key found for this signature in database GPG Key ID: 1B8D649257DB0829
  1. 3
      src/bech32.cpp
  2. 33
      src/test/bech32_tests.cpp

3
src/bech32.cpp

@ -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;

33
src/test/bech32_tests.cpp

@ -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()

Loading…
Cancel
Save