bitcoinaddressvalidator.cpp
1 // Copyright (c) 2011-2018 The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <qt/bitcoinaddressvalidator.h> 6 7 #include <key_io.h> 8 9 /* Base58 characters are: 10 "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" 11 12 This is: 13 - All numbers except for '0' 14 - All upper-case letters except for 'I' and 'O' 15 - All lower-case letters except for 'l' 16 */ 17 18 BitcoinAddressEntryValidator::BitcoinAddressEntryValidator(QObject *parent) : 19 QValidator(parent) 20 { 21 } 22 23 QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &pos) const 24 { 25 Q_UNUSED(pos); 26 27 // Empty address is "intermediate" input 28 if (input.isEmpty()) 29 return QValidator::Intermediate; 30 31 // Correction 32 for (int idx = 0; idx < input.size();) 33 { 34 bool removeChar = false; 35 QChar ch = input.at(idx); 36 // Corrections made are very conservative on purpose, to avoid 37 // users unexpectedly getting away with typos that would normally 38 // be detected, and thus sending to the wrong address. 39 switch(ch.unicode()) 40 { 41 // Qt categorizes these as "Other_Format" not "Separator_Space" 42 case 0x200B: // ZERO WIDTH SPACE 43 case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE 44 removeChar = true; 45 break; 46 default: 47 break; 48 } 49 50 // Remove whitespace 51 if (ch.isSpace()) 52 removeChar = true; 53 54 // To next character 55 if (removeChar) 56 input.remove(idx, 1); 57 else 58 ++idx; 59 } 60 61 // Validation 62 QValidator::State state = QValidator::Acceptable; 63 for (int idx = 0; idx < input.size(); ++idx) 64 { 65 int ch = input.at(idx).unicode(); 66 67 if (((ch >= '0' && ch<='9') || 68 (ch >= 'a' && ch<='z') || 69 (ch >= 'A' && ch<='Z')) && 70 ch != 'I' && ch != 'O') // Characters invalid in both Base58 and Bech32 71 { 72 // Alphanumeric and not a 'forbidden' character 73 } 74 else 75 { 76 state = QValidator::Invalid; 77 } 78 } 79 80 return state; 81 } 82 83 BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) : 84 QValidator(parent) 85 { 86 } 87 88 QValidator::State BitcoinAddressCheckValidator::validate(QString &input, int &pos) const 89 { 90 Q_UNUSED(pos); 91 // Validate the passed Bitcoin address 92 if (IsValidDestinationString(input.toStdString())) { 93 return QValidator::Acceptable; 94 } 95 96 return QValidator::Invalid; 97 }