Report encoding type in bech32 error message

pull/23577/head
Samuel Dobson 3 years ago
parent 92f0cafdca
commit c8b9a224e7

@ -7,6 +7,7 @@
#include <util/vector.h> #include <util/vector.h>
#include <assert.h> #include <assert.h>
#include <optional>
namespace bech32 namespace bech32
{ {
@ -539,6 +540,7 @@ std::string LocateErrors(const std::string& str, std::vector<int>& error_locatio
// We attempt error detection with both bech32 and bech32m, and choose the one with the fewest errors // We attempt error detection with both bech32 and bech32m, and choose the one with the fewest errors
// We can't simply use the segwit version, because that may be one of the errors // We can't simply use the segwit version, because that may be one of the errors
std::optional<Encoding> error_encoding;
for (Encoding encoding : {Encoding::BECH32, Encoding::BECH32M}) { for (Encoding encoding : {Encoding::BECH32, Encoding::BECH32M}) {
std::vector<int> possible_errors; std::vector<int> possible_errors;
// Recall that (ExpandHRP(hrp) ++ values) is interpreted as a list of coefficients of a polynomial // Recall that (ExpandHRP(hrp) ++ values) is interpreted as a list of coefficients of a polynomial
@ -657,9 +659,13 @@ std::string LocateErrors(const std::string& str, std::vector<int>& error_locatio
if (error_locations.empty() || (!possible_errors.empty() && possible_errors.size() < error_locations.size())) { if (error_locations.empty() || (!possible_errors.empty() && possible_errors.size() < error_locations.size())) {
error_locations = std::move(possible_errors); error_locations = std::move(possible_errors);
if (!error_locations.empty()) error_encoding = encoding;
} }
} }
return "Invalid checksum"; return error_encoding == Encoding::BECH32M ? "Invalid Bech32m checksum"
: error_encoding == Encoding::BECH32 ? "Invalid Bech32 checksum"
: "Invalid checksum";
} }
} // namespace bech32 } // namespace bech32

@ -87,8 +87,8 @@ BOOST_AUTO_TEST_CASE(bech32_testvectors_invalid)
{"Invalid separator position", {0}}, {"Invalid separator position", {0}},
{"Invalid character or mixed case", {3, 4, 5, 7}}, {"Invalid character or mixed case", {3, 4, 5, 7}},
{"Invalid character or mixed case", {3}}, {"Invalid character or mixed case", {3}},
{"Invalid checksum", {11}}, {"Invalid Bech32 checksum", {11}},
{"Invalid checksum", {9, 16}}, {"Invalid Bech32 checksum", {9, 16}},
}; };
static_assert(std::size(CASES) == std::size(ERRORS), "Bech32 CASES and ERRORS should have the same length"); static_assert(std::size(CASES) == std::size(ERRORS), "Bech32 CASES and ERRORS should have the same length");
@ -140,8 +140,8 @@ BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)
{"Invalid checksum", {}}, {"Invalid checksum", {}},
{"Invalid separator position", {0}}, {"Invalid separator position", {0}},
{"Invalid separator position", {0}}, {"Invalid separator position", {0}},
{"Invalid checksum", {21}}, {"Invalid Bech32m checksum", {21}},
{"Invalid checksum", {13, 32}}, {"Invalid Bech32m checksum", {13, 32}},
}; };
static_assert(std::size(CASES) == std::size(ERRORS), "Bech32m CASES and ERRORS should have the same length"); static_assert(std::size(CASES) == std::size(ERRORS), "Bech32m CASES and ERRORS should have the same length");

@ -67,13 +67,13 @@ class InvalidAddressErrorMessageTest(BitcoinTestFramework):
self.check_invalid(BECH32_INVALID_VERSION, 'Invalid Bech32 address witness version') self.check_invalid(BECH32_INVALID_VERSION, 'Invalid Bech32 address witness version')
self.check_invalid(BECH32_INVALID_V0_SIZE, 'Invalid Bech32 v0 address data size') self.check_invalid(BECH32_INVALID_V0_SIZE, 'Invalid Bech32 v0 address data size')
self.check_invalid(BECH32_TOO_LONG, 'Bech32 string too long', list(range(90, 108))) self.check_invalid(BECH32_TOO_LONG, 'Bech32 string too long', list(range(90, 108)))
self.check_invalid(BECH32_ONE_ERROR, 'Invalid checksum', [9]) self.check_invalid(BECH32_ONE_ERROR, 'Invalid Bech32 checksum', [9])
self.check_invalid(BECH32_TWO_ERRORS, 'Invalid checksum', [22, 43]) self.check_invalid(BECH32_TWO_ERRORS, 'Invalid Bech32 checksum', [22, 43])
self.check_invalid(BECH32_ONE_ERROR_CAPITALS, 'Invalid checksum', [38]) self.check_invalid(BECH32_ONE_ERROR_CAPITALS, 'Invalid Bech32 checksum', [38])
self.check_invalid(BECH32_NO_SEPARATOR, 'Missing separator') self.check_invalid(BECH32_NO_SEPARATOR, 'Missing separator')
self.check_invalid(BECH32_INVALID_CHAR, 'Invalid Base 32 character', [8]) self.check_invalid(BECH32_INVALID_CHAR, 'Invalid Base 32 character', [8])
self.check_invalid(BECH32_MULTISIG_TWO_ERRORS, 'Invalid checksum', [19, 30]) self.check_invalid(BECH32_MULTISIG_TWO_ERRORS, 'Invalid Bech32 checksum', [19, 30])
self.check_invalid(BECH32_WRONG_VERSION, 'Invalid checksum', [5]) self.check_invalid(BECH32_WRONG_VERSION, 'Invalid Bech32 checksum', [5])
# Valid Bech32 # Valid Bech32
self.check_valid(BECH32_VALID) self.check_valid(BECH32_VALID)

Loading…
Cancel
Save