Skip to content

Commit a4fe701

Browse files
committed
Make Bech32 LocateErrors return error list rather than using out-arg
1 parent 2fa4fd1 commit a4fe701

File tree

4 files changed

+22
-23
lines changed

4 files changed

+22
-23
lines changed

Diff for: src/bech32.cpp

+16-11
Original file line numberDiff line numberDiff line change
@@ -396,23 +396,28 @@ DecodeResult Decode(const std::string& str) {
396396
}
397397

398398
/** Find index of an incorrect character in a Bech32 string. */
399-
std::string LocateErrors(const std::string& str, std::vector<int>& error_locations) {
399+
std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str) {
400+
std::vector<int> error_locations{};
401+
400402
if (str.size() > 90) {
401403
error_locations.resize(str.size() - 90);
402404
std::iota(error_locations.begin(), error_locations.end(), 90);
403-
return "Bech32 string too long";
405+
return std::make_pair("Bech32 string too long", std::move(error_locations));
404406
}
407+
405408
if (!CheckCharacters(str, error_locations)){
406-
return "Invalid character or mixed case";
409+
return std::make_pair("Invalid character or mixed case", std::move(error_locations));
407410
}
411+
408412
size_t pos = str.rfind('1');
409413
if (pos == str.npos) {
410-
return "Missing separator";
414+
return std::make_pair("Missing separator", std::vector<int>{});
411415
}
412416
if (pos == 0 || pos + 7 > str.size()) {
413417
error_locations.push_back(pos);
414-
return "Invalid separator position";
418+
return std::make_pair("Invalid separator position", std::move(error_locations));
415419
}
420+
416421
std::string hrp;
417422
for (size_t i = 0; i < pos; ++i) {
418423
hrp += LowerCase(str[i]);
@@ -425,7 +430,7 @@ std::string LocateErrors(const std::string& str, std::vector<int>& error_locatio
425430
int8_t rev = CHARSET_REV[c];
426431
if (rev == -1) {
427432
error_locations.push_back(i);
428-
return "Invalid Base 32 character";
433+
return std::make_pair("Invalid Base 32 character", std::move(error_locations));
429434
}
430435
values[i - pos - 1] = rev;
431436
}
@@ -545,19 +550,19 @@ std::string LocateErrors(const std::string& str, std::vector<int>& error_locatio
545550
}
546551
} else {
547552
// No errors
548-
error_locations.clear();
549-
return "";
553+
return std::make_pair("", std::vector<int>{});
550554
}
551555

552556
if (error_locations.empty() || (!possible_errors.empty() && possible_errors.size() < error_locations.size())) {
553557
error_locations = std::move(possible_errors);
554558
if (!error_locations.empty()) error_encoding = encoding;
555559
}
556560
}
557-
return error_encoding == Encoding::BECH32M ? "Invalid Bech32m checksum"
558-
: error_encoding == Encoding::BECH32 ? "Invalid Bech32 checksum"
559-
: "Invalid checksum";
561+
std::string error_message = error_encoding == Encoding::BECH32M ? "Invalid Bech32m checksum"
562+
: error_encoding == Encoding::BECH32 ? "Invalid Bech32 checksum"
563+
: "Invalid checksum";
560564

565+
return std::make_pair(error_message, std::move(error_locations));
561566
}
562567

563568
} // namespace bech32

Diff for: src/bech32.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ struct DecodeResult
4646
DecodeResult Decode(const std::string& str);
4747

4848
/** Return the positions of errors in a Bech32 string. */
49-
std::string LocateErrors(const std::string& str, std::vector<int>& error_locations);
49+
std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str);
5050

5151
} // namespace bech32
5252

Diff for: src/key_io.cpp

+3-7
Original file line numberDiff line numberDiff line change
@@ -188,13 +188,9 @@ CTxDestination DecodeDestination(const std::string& str, const CChainParams& par
188188
}
189189

190190
// Perform Bech32 error location
191-
if (!error_locations) {
192-
std::vector<int> dummy_errors;
193-
error_str = bech32::LocateErrors(str, dummy_errors);
194-
} else {
195-
error_str = bech32::LocateErrors(str, *error_locations);
196-
}
197-
191+
auto res = bech32::LocateErrors(str);
192+
error_str = res.first;
193+
if (error_locations) *error_locations = std::move(res.second);
198194
return CNoDestination();
199195
}
200196
} // namespace

Diff for: src/test/bech32_tests.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ BOOST_AUTO_TEST_CASE(bech32_testvectors_invalid)
9797
const auto& err = ERRORS[i];
9898
const auto dec = bech32::Decode(str);
9999
BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
100-
std::vector<int> error_locations;
101-
std::string error = bech32::LocateErrors(str, error_locations);
100+
auto [error, error_locations] = bech32::LocateErrors(str);
102101
BOOST_CHECK_EQUAL(err.first, error);
103102
BOOST_CHECK(err.second == error_locations);
104103
i++;
@@ -150,8 +149,7 @@ BOOST_AUTO_TEST_CASE(bech32m_testvectors_invalid)
150149
const auto& err = ERRORS[i];
151150
const auto dec = bech32::Decode(str);
152151
BOOST_CHECK(dec.encoding == bech32::Encoding::INVALID);
153-
std::vector<int> error_locations;
154-
std::string error = bech32::LocateErrors(str, error_locations);
152+
auto [error, error_locations] = bech32::LocateErrors(str);
155153
BOOST_CHECK_EQUAL(err.first, error);
156154
BOOST_CHECK(err.second == error_locations);
157155
i++;

0 commit comments

Comments
 (0)