diff --git a/src/bech32.cpp b/src/bech32.cpp index 573eac58b..2889f8f99 100644 --- a/src/bech32.cpp +++ b/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; diff --git a/src/test/bech32_tests.cpp b/src/test/bech32_tests.cpp index ce4cddd64..f71ca1bf2 100644 --- a/src/test/bech32_tests.cpp +++ b/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 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 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()