Changeset View
Changeset View
Standalone View
Standalone View
src/qt/bitcoinaddressvalidator.cpp
// Copyright (c) 2011-2014 The Bitcoin Core developers | // Copyright (c) 2011-2014 The Bitcoin Core developers | ||||
// Copyright (c) 2017 The Bitcoin developers | |||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "bitcoinaddressvalidator.h" | #include "bitcoinaddressvalidator.h" | ||||
#include "cashaddr.h" | |||||
#include "dstencode.h" | #include "dstencode.h" | ||||
/* Base58 characters are: | /* Base58 characters are: | ||||
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" | "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" | ||||
This is: | This is: | ||||
- All numbers except for '0' | - All numbers except for '0' | ||||
- All upper-case letters except for 'I' and 'O' | - All upper-case letters except for 'I' and 'O' | ||||
- All lower-case letters except for 'l' | - All lower-case letters except for 'l' | ||||
*/ | */ | ||||
static bool ValidLegacyInput(const QString &input) { | |||||
// Alphanumeric and not a 'forbidden' character | |||||
for (QChar ch : input) { | |||||
if (!(((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || | |||||
(ch >= 'A' && ch <= 'Z')) && | |||||
ch != 'l' && ch != 'I' && ch != '0' && ch != 'O')) | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
BitcoinAddressEntryValidator::BitcoinAddressEntryValidator(QObject *parent) | static bool ValidCashaddrInput(const QString &prefix, const QString &input) { | ||||
: QValidator(parent) {} | |||||
std::vector<uint8_t> charset = cashaddr::EncodingCharset(); | |||||
// Input may be incomplete. We're checking if it so far looks good. | |||||
for (int i = 0; i < input.size(); ++i) { | |||||
char ch = std::tolower(input[i].toLatin1()); | |||||
// Does the input have the right prefix? | |||||
if (i < prefix.size()) { | |||||
if (ch != prefix[i].toLatin1()) { | |||||
return false; | |||||
} | |||||
continue; | |||||
} | |||||
// Payload, must use cashaddr charset. | |||||
if (std::find(begin(charset), end(charset), ch) == end(charset)) { | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
BitcoinAddressEntryValidator::BitcoinAddressEntryValidator( | |||||
const std::string &cashaddrprefix, QObject *parent) | |||||
: QValidator(parent), cashaddrprefix(cashaddrprefix) {} | |||||
QValidator::State BitcoinAddressEntryValidator::validate(QString &input, | QValidator::State BitcoinAddressEntryValidator::validate(QString &input, | ||||
int &pos) const { | int &pos) const { | ||||
Q_UNUSED(pos); | Q_UNUSED(pos); | ||||
// Empty address is "intermediate" input | // Empty address is "intermediate" input | ||||
if (input.isEmpty()) return QValidator::Intermediate; | if (input.isEmpty()) return QValidator::Intermediate; | ||||
Show All 20 Lines | for (int idx = 0; idx < input.size();) { | ||||
// To next character | // To next character | ||||
if (removeChar) | if (removeChar) | ||||
input.remove(idx, 1); | input.remove(idx, 1); | ||||
else | else | ||||
++idx; | ++idx; | ||||
} | } | ||||
// Validation | // Validation | ||||
QValidator::State state = QValidator::Acceptable; | const QString cashPrefix = QString::fromStdString(cashaddrprefix) + ":"; | ||||
for (int idx = 0; idx < input.size(); ++idx) { | return (ValidLegacyInput(input) || ValidCashaddrInput(cashPrefix, input)) | ||||
int ch = input.at(idx).unicode(); | ? QValidator::Acceptable | ||||
: QValidator::Invalid; | |||||
if (((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || | |||||
(ch >= 'A' && ch <= 'Z')) && | |||||
ch != 'l' && ch != 'I' && ch != '0' && ch != 'O') { | |||||
// Alphanumeric and not a 'forbidden' character | |||||
} else { | |||||
state = QValidator::Invalid; | |||||
} | |||||
} | |||||
return state; | |||||
} | } | ||||
BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) | BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) | ||||
: QValidator(parent) {} | : QValidator(parent) {} | ||||
QValidator::State BitcoinAddressCheckValidator::validate(QString &input, | QValidator::State BitcoinAddressCheckValidator::validate(QString &input, | ||||
int &pos) const { | int &pos) const { | ||||
Q_UNUSED(pos); | Q_UNUSED(pos); | ||||
// Validate the passed Bitcoin address | // Validate the passed Bitcoin address | ||||
if (IsValidDestinationString(input.toStdString())) { | if (IsValidDestinationString(input.toStdString())) { | ||||
return QValidator::Acceptable; | return QValidator::Acceptable; | ||||
} | } | ||||
return QValidator::Invalid; | return QValidator::Invalid; | ||||
} | } |