Repository: bitcoin/bitcoin
File: src/bech32.cpp (C++)

Code before:
    if (pos == str.npos || pos == 0 || pos + 7 > str.size()) {
        return {};
    }
    data values(str.size() - 1 - pos);
    for (size_t i = 0; i < str.size() - 1 - pos; ++i) {
        unsigned char c = str[i + pos + 1];
        int8_t rev = CHARSET_REV[c];

        if (rev == -1) {
            return {};
        }
        values[i] = rev;
    }
    std::string hrp;
    for (size_t i = 0; i < pos; ++i) {
        hrp += LowerCase(str[i]);
    }
    Encoding result = VerifyChecksum(hrp, values);
    if (result == Encoding::INVALID) return {};
    return {result, std::move(hrp), data(values.begin(), values.end() - 6)};
}

/** Find index of an incorrect character in a Bech32 string. */
std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, CharLimit limit) {
    std::vector<int> error_locations{};

    if (str.size() > limit) {
        error_locations.resize(str.size() - limit);
        std::iota(error_locations.begin(), error_locations.end(), static_cast<int>(limit));
        return std::make_pair("Bech32 string too long", std::move(error_locations));
    }

    if (!CheckCharacters(str, error_locations)){
        return std::make_pair("Invalid character or mixed case", std::move(error_locations));
    }

    size_t pos = str.rfind('1');
    if (pos == str.npos) {
        return std::make_pair("Missing separator", std::vector<int>{});
    }
    if (pos == 0 || pos + 7 > str.size()) {
        error_locations.push_back(pos);
        return std::make_pair("Invalid separator position", std::move(error_locations));
    }

    std::string hrp;
    for (size_t i = 0; i < pos; ++i) {
        hrp += LowerCase(str[i]);
    }

    size_t length = str.size() - 1 - pos; // length of data part

Review comment (suggestion):
I worked around this 90 in my pr in https://github.com/bitcoin/bitcoin/pull/29607/files#diff-f146300624c06d2e08aadf500952294148a1785edd6ff2e8b50f13b2c08255edL315 (though I'm not sure why it's not replaced here with `limit`) - I will try to review this in more detail next week

Code after:
    std::vector<int> errors;
    if (!CheckCharacters(str, errors)) return {};
    size_t pos = str.rfind('1');
    if (str.size() > limit) return {};
    if (pos == str.npos || pos == 0 || pos + CHECKSUM_SIZE >= str.size()) {
        return {};
    }
    data values(str.size() - 1 - pos);
    for (size_t i = 0; i < str.size() - 1 - pos; ++i) {
        unsigned char c = str[i + pos + 1];
        int8_t rev = CHARSET_REV[c];

        if (rev == -1) {
            return {};
        }
        values[i] = rev;
    }
    std::string hrp;
    for (size_t i = 0; i < pos; ++i) {
        hrp += LowerCase(str[i]);
    }
    Encoding result = VerifyChecksum(hrp, values);
    if (result == Encoding::INVALID) return {};
    return {result, std::move(hrp), data(values.begin(), values.end() - CHECKSUM_SIZE)};
}

/** Find index of an incorrect character in a Bech32 string. */
std::pair<std::string, std::vector<int>> LocateErrors(const std::string& str, CharLimit limit) {
    std::vector<int> error_locations{};

    if (str.size() > limit) {
        error_locations.resize(str.size() - limit);
        std::iota(error_locations.begin(), error_locations.end(), static_cast<int>(limit));
        return std::make_pair("Bech32 string too long", std::move(error_locations));
    }

    if (!CheckCharacters(str, error_locations)){
        return std::make_pair("Invalid character or mixed case", std::move(error_locations));
    }

    size_t pos = str.rfind('1');
    if (pos == str.npos) {
        return std::make_pair("Missing separator", std::vector<int>{});
    }
    if (pos == 0 || pos + CHECKSUM_SIZE >= str.size()) {
        error_locations.push_back(pos);
        return std::make_pair("Invalid separator position", std::move(error_locations));
    }

    std::string hrp;
    for (size_t i = 0; i < pos; ++i) {