Filter out whitespace and zero-width non-breaking spaces in validator
[novacoin.git] / src / qt / bitcoinaddressvalidator.cpp
1 #include "bitcoinaddressvalidator.h"
2
3 /* Base58 characters are:
4      "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
5
6   This is:
7   - All numbers except for '0'
8   - All uppercase letters except for 'I' and 'O'
9   - All lowercase letters except for 'l'
10
11   User friendly Base58 input can map
12   - 'l' and 'I' to '1'
13   - '0' and 'O' to 'o'
14 */
15
16 BitcoinAddressValidator::BitcoinAddressValidator(QObject *parent) :
17     QValidator(parent)
18 {
19 }
20
21 QValidator::State BitcoinAddressValidator::validate(QString &input, int &pos) const
22 {
23     // Correction
24     for(int idx=0; idx<input.size();)
25     {
26         bool removeChar = false;
27         QChar ch = input.at(idx);
28         // Transform characters that are visually close
29         switch(ch.unicode())
30         {
31         case 'l':
32         case 'I':
33             input[idx] = QChar('1');
34             break;
35         case '0':
36         case 'O':
37             input[idx] = QChar('o');
38             break;
39         // Qt categorizes these as "Other_Format" not "Separator_Space"
40         case 0x200B: // ZERO WIDTH SPACE
41         case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
42             removeChar = true;
43             break;
44         default:
45             break;
46         }
47         // Remove whitespace
48         if(ch.isSpace())
49             removeChar = true;
50         // To next character
51         if(removeChar)
52             input.remove(idx, 1);
53         else
54             ++idx;
55     }
56
57     // Validation
58     QValidator::State state = QValidator::Acceptable;
59     for(int idx=0; idx<input.size(); ++idx)
60     {
61         int ch = input.at(idx).unicode();
62
63         if(((ch >= '0' && ch<='9') ||
64            (ch >= 'a' && ch<='z') ||
65            (ch >= 'A' && ch<='Z')) &&
66            ch != 'l' && ch != 'I' && ch != '0' && ch != 'O')
67         {
68             // Alphanumeric and not a 'forbidden' character
69         }
70         else
71         {
72             state = QValidator::Invalid;
73         }
74     }
75
76     // Empty address is "intermediate" input
77     if(input.isEmpty())
78     {
79         state = QValidator::Intermediate;
80     }
81
82     return state;
83 }