Files
thehub/hub-qt/bitcoinaddressvalidator.cpp
T

136 lines
4.1 KiB
C++
Raw Permalink Normal View History

/*
2017-11-13 23:09:33 +01:00
* This file is part of the Flowee project
* Copyright (c) 2011-2014 The Bitcoin Core developers
2019-08-09 20:50:38 +02:00
* Copyright (C) 2017,2019 Tom Zander <tomz@freedommail.ch>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
2013-11-04 16:20:43 +01:00
2011-05-13 22:00:27 +02:00
#include "bitcoinaddressvalidator.h"
2019-04-11 11:33:27 +02:00
#include <encodings_legacy.h>
#include <Application.h>
2019-08-09 20:50:38 +02:00
#include <cashaddr.h>
/* Base58 characters are:
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
This is:
- All numbers except for '0'
2012-07-26 00:48:39 +00:00
- All upper-case letters except for 'I' and 'O'
- All lower-case letters except for 'l'
*/
BitcoinAddressEntryValidator::BitcoinAddressEntryValidator(QObject *parent) :
2011-06-03 10:52:49 +02:00
QValidator(parent)
2011-05-13 22:00:27 +02:00
{
}
QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &pos) const
{
Q_UNUSED(pos);
// Empty address is "intermediate" input
if (input.isEmpty())
return QValidator::Intermediate;
2019-08-09 20:50:38 +02:00
enum Type {
Old,
Cash
};
static const QString CashPrefix = "bitcoincash:";
Type type = (input.startsWith('q') || input.startsWith('p')
|| input.startsWith(CashPrefix.left(10))) ? Cash : Old;
2019-08-09 20:50:38 +02:00
// Correction
2019-08-09 20:50:38 +02:00
for (int idx = 0; idx < input.size();) {
bool removeChar = false;
QChar ch = input.at(idx);
// Corrections made are very conservative on purpose, to avoid
// users unexpectedly getting away with typos that would normally
// be detected, and thus sending to the wrong address.
switch(ch.unicode())
{
// Qt categorizes these as "Other_Format" not "Separator_Space"
case 0x200B: // ZERO WIDTH SPACE
case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
removeChar = true;
break;
default:
break;
}
// Remove whitespace
if (ch.isSpace())
removeChar = true;
// To next character
2019-08-09 20:50:38 +02:00
if (removeChar) {
input.remove(idx, 1);
2019-08-09 20:50:38 +02:00
} else {
if (type == Cash && ch.isUpper())
input[idx] = input.at(idx).toLower();
++idx;
2019-08-09 20:50:38 +02:00
}
}
2011-06-03 10:52:49 +02:00
int idx = 0;
if (type == Cash) { // skip over the 'bitcoincash:' prefix
QString left = input.left(12);
if (CashPrefix.left(left.size()) == left)
idx = left.size();
}
for (; idx < input.size(); ++idx) {
2011-06-03 10:52:49 +02:00
int ch = input.at(idx).unicode();
2019-08-09 20:50:38 +02:00
switch (type) {
case Old:
// Alphanumeric and not a 'forbidden' character
2019-08-09 20:50:38 +02:00
if (!(((ch >= '0' && ch<='9') || (ch >= 'a' && ch<='z') || (ch >= 'A' && ch<='Z'))
&& ch != 'l' && ch != 'I' && ch != '0' && ch != 'O'))
return QValidator::Invalid;
break;
case Cash:
if (!(((ch >= '0' && ch<='9') || (ch >= 'a' && ch<='z'))
&& ch != 'i' && ch != 'b' && ch != 'i' && ch != 'o'))
return QValidator::Invalid;
break;
2011-06-03 10:52:49 +02:00
}
}
2019-08-09 20:50:38 +02:00
return QValidator::Acceptable;
}
BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) :
QValidator(parent)
{
}
QValidator::State BitcoinAddressCheckValidator::validate(QString &input, int &pos) const
{
Q_UNUSED(pos);
// Validate the passed Bitcoin address
CBitcoinAddress addr(input.toStdString());
if (addr.IsValid())
return QValidator::Acceptable;
2019-08-09 20:50:38 +02:00
CashAddress::Content c = CashAddress::decodeCashAddrContent(input.toStdString(), "bitcoincash");
if ((c.type == CashAddress::PUBKEY_TYPE || c.type == CashAddress::SCRIPT_TYPE) && c.hash.size() == 20)
2019-08-09 20:50:38 +02:00
return QValidator::Acceptable;
return QValidator::Invalid;
}