Changeset View
Changeset View
Standalone View
Standalone View
libs/editor/simpleipv6addressvalidator.cpp
Show All 15 Lines | |||||
16 | 16 | | |||
17 | You should have received a copy of the GNU General Public License | 17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | 19 | */ | ||
20 | 20 | | |||
21 | #include "simpleipv6addressvalidator.h" | 21 | #include "simpleipv6addressvalidator.h" | ||
22 | 22 | | |||
23 | #include <QStringList> | 23 | #include <QStringList> | ||
24 | #include <QVector> | ||||
24 | 25 | | |||
25 | SimpleIpV6AddressValidator::SimpleIpV6AddressValidator(QObject *parent) | 26 | SimpleIpV6AddressValidator::SimpleIpV6AddressValidator(QObject *parent, AddressStyle style) | ||
26 | : QValidator(parent) | 27 | : QValidator(parent) | ||
28 | , m_addressStyle(style) | ||||
27 | { | 29 | { | ||
30 | switch (style) { | ||||
31 | case Base: | ||||
32 | m_validator.setRegularExpression(QRegularExpression(QLatin1String("([0-9a-fA-F]{1,4}|:)+"))); | ||||
33 | break; | ||||
34 | case WithCidr: | ||||
35 | m_validator.setRegularExpression(QRegularExpression(QLatin1String("([0-9a-fA-F]{1,4}|:){2,15}/[0-9]{1,3}"))); | ||||
36 | break; | ||||
37 | case WithPort: | ||||
38 | m_validator.setRegularExpression(QRegularExpression(QLatin1String("\\[([0-9a-fA-F]{1,4}|:)+\\]:[0-9]{1,5}"))); | ||||
39 | } | ||||
28 | } | 40 | } | ||
29 | 41 | | |||
30 | SimpleIpV6AddressValidator::~SimpleIpV6AddressValidator() | 42 | SimpleIpV6AddressValidator::~SimpleIpV6AddressValidator() | ||
31 | { | 43 | { | ||
32 | } | 44 | } | ||
33 | 45 | | |||
34 | QValidator::State SimpleIpV6AddressValidator::validate(QString &address, int &pos) const | 46 | QValidator::State SimpleIpV6AddressValidator::validate(QString &address, int &pos) const | ||
35 | { | 47 | { | ||
36 | if (QValidator::Invalid == checkWithInputMask(address, pos)) { | 48 | if (QValidator::Invalid == checkWithInputMask(address, pos)) | ||
37 | return QValidator::Invalid; | 49 | return QValidator::Invalid; | ||
38 | } | | |||
39 | 50 | | |||
pino: unrelated changes | |||||
40 | return checkTetradsRanges(address); | 51 | return checkTetradsRanges(address); | ||
41 | } | 52 | } | ||
42 | 53 | | |||
43 | QValidator::State SimpleIpV6AddressValidator::checkWithInputMask(QString &value, int &pos) const | 54 | QValidator::State SimpleIpV6AddressValidator::checkWithInputMask(QString &value, int &pos) const | ||
44 | { | 55 | { | ||
45 | QRegExpValidator v(QRegExp(QLatin1String("([0-9a-fA-F]{1,4}|:)+")), nullptr); | 56 | return m_validator.validate(value, pos); | ||
46 | | ||||
47 | return v.validate(value, pos); | | |||
48 | } | 57 | } | ||
49 | 58 | | |||
50 | QValidator::State SimpleIpV6AddressValidator::checkTetradsRanges(QString &value) const | 59 | QValidator::State SimpleIpV6AddressValidator::checkTetradsRanges(QString &value) const | ||
51 | { | 60 | { | ||
52 | const QStringList addrParts = value.split(QLatin1Char(':')); | 61 | QStringList addrParts; | ||
53 | int number = addrParts.size(); | 62 | QStringList cidrParts; | ||
54 | if (number > 8) { | 63 | QStringList portParts; | ||
64 | bool foundBracket = false; | ||||
65 | QValidator::State result = QValidator::Acceptable; | ||||
66 | | ||||
67 | switch (m_addressStyle) { | ||||
68 | case Base: | ||||
69 | addrParts = value.split(QLatin1Char(':')); | ||||
70 | break; | ||||
71 | | ||||
72 | case WithCidr: | ||||
73 | cidrParts = value.split(QLatin1Char('/')); | ||||
74 | addrParts = cidrParts[0].split(QLatin1Char(':')); | ||||
75 | break; | ||||
76 | | ||||
77 | case WithPort: | ||||
78 | if (value.isEmpty()) | ||||
79 | return QValidator::Intermediate; | ||||
80 | if (value[0] != '[') { | ||||
81 | return QValidator::Invalid; | ||||
82 | } else { | ||||
83 | // Input: "[1:2:3:4:5:6:7:8]:123" | ||||
84 | // bracketParts: "[1:2:3:4:5:6:7:8" , ":123" | ||||
85 | // addrParts: "" , "1:2:3:4:5:6:7:8" | ||||
86 | // portParts: "", "123" | ||||
87 | QStringList bracketParts = value.split(QLatin1Char(']')); | ||||
88 | if (bracketParts.size() < 2) | ||||
89 | portParts = QStringList(); | ||||
90 | else { | ||||
91 | foundBracket = true; | ||||
92 | if (!bracketParts[1].isEmpty() && bracketParts[1][0] != ':') | ||||
55 | return QValidator::Invalid; | 93 | return QValidator::Invalid; | ||
94 | else | ||||
95 | portParts = bracketParts[1].split(QLatin1Char(':')); | ||||
56 | } | 96 | } | ||
97 | addrParts = bracketParts[0].split(QLatin1Char('['))[1].split(QLatin1Char(':')); | ||||
98 | } | ||||
99 | } | ||||
100 | | ||||
101 | int number = addrParts.size(); | ||||
102 | // There is no case where can be more than 8 colons (9 parts) | ||||
103 | // and only one unusual case where there are 8 colons (1:2:3:4:5:6:7::) | ||||
104 | if (number > 9) | ||||
105 | return QValidator::Invalid; | ||||
106 | else if (number == 9 && (!addrParts[7].isEmpty() || !addrParts[8].isEmpty())) | ||||
107 | return QValidator::Invalid; | ||||
57 | 108 | | |||
58 | // lets check address parts | 109 | // lets check address parts | ||
59 | bool emptypresent = false; | 110 | bool emptypresent = false; | ||
60 | int i = 1; | 111 | int i = 1; | ||
61 | Q_FOREACH (QString part, addrParts) { // krazy:exclude=Q_FOREACH | 112 | for (QString part : addrParts) { // krazy:exclude=Q_FOREACH | ||
pino: as above, unrelated change | |||||
62 | if (part.isEmpty() && i < number) { | 113 | if (part.isEmpty() && i < number) { | ||
63 | if (emptypresent) { | 114 | // There is only one case where you can have 3 empty parts | ||
115 | // and that is when you have the string: "::" which is valid | ||||
116 | // and useful and of course it can also be extended to ::123 for | ||||
117 | // instance. Anywhere other than the beginning though, having 3 empty | ||||
118 | // parts indicates either a run of 3 colons ("1:::6")" or two sets of | ||||
119 | // 2 colons ("1:2::3:4::") which are always invalid | ||||
120 | if (emptypresent && i != 2) { | ||||
64 | // qCDebug(PLASMA_NM) << "part.isEmpty()"; | 121 | // qCDebug(PLASMA_NM) << "part.isEmpty()"; | ||
65 | return QValidator::Invalid; | 122 | return QValidator::Invalid; | ||
66 | } | 123 | } else { | ||
67 | else if (!emptypresent) | 124 | // If this is an empty part then set it to zero to not fail | ||
68 | { | 125 | // the next test | ||
69 | part.setNum(0,16); | 126 | part.setNum(0,16); | ||
70 | emptypresent = true; | 127 | emptypresent = true; | ||
71 | } | 128 | } | ||
72 | } | 129 | } | ||
73 | i++; | 130 | i++; | ||
74 | 131 | | |||
75 | bool ok; | 132 | bool ok; | ||
76 | if (part.toInt(&ok, 16) > 65535) { | 133 | if (part.toInt(&ok, 16) > 65535) { | ||
77 | return QValidator::Invalid; | 134 | return QValidator::Invalid; | ||
78 | } | 135 | } | ||
79 | } | 136 | } | ||
80 | 137 | | |||
81 | if (number < 8 && !emptypresent) | 138 | // A special case: a single colon needs to be Intermediate not Acceptable | ||
139 | if (number == 2 && addrParts[0].isEmpty() && addrParts[1].isEmpty()) | ||||
140 | result = QValidator::Intermediate; | ||||
141 | | ||||
142 | // Another special case: a single colon followed by something (i.e. ":123" | ||||
143 | // is invalid | ||||
144 | else if (number > 1 && addrParts[0].isEmpty() && !addrParts[1].isEmpty()) | ||||
145 | result = QValidator::Invalid; | ||||
146 | | ||||
147 | // If we don't have 8 parts yet and none of them are empty we aren't done yet | ||||
148 | else if (number < 8 && !emptypresent) | ||||
149 | result = QValidator::Intermediate; | ||||
150 | | ||||
151 | // If we have 8 parts but the last one is empty we aren't done yet | ||||
152 | else if (number == 8 && addrParts[7].isEmpty()) | ||||
153 | result = QValidator::Intermediate; | ||||
154 | | ||||
155 | if (m_addressStyle == WithCidr) { | ||||
156 | int cidrSize = cidrParts.size(); | ||||
157 | | ||||
158 | // If we have a '/' and the basic address portion is not | ||||
159 | // yet complete (i.e. Intermediate) then the whole thing is Invalid | ||||
160 | if (cidrSize == 2 && result == QValidator::Intermediate) | ||||
161 | return QValidator::Invalid; | ||||
162 | | ||||
163 | if (cidrSize == 1 || (cidrSize == 2 && cidrParts[1].isEmpty())) | ||||
82 | return QValidator::Intermediate; | 164 | return QValidator::Intermediate; | ||
83 | 165 | | |||
84 | return QValidator::Acceptable; | 166 | int cidrValue = cidrParts[1].toInt(); | ||
167 | if (cidrValue > 128) | ||||
168 | return QValidator::Invalid; | ||||
169 | } else if (m_addressStyle == WithPort) { | ||||
170 | int portSize = portParts.size(); | ||||
171 | | ||||
172 | // If we have a ']' and the basic address portion is not | ||||
173 | // yet complete (i.e. Intermediate) then the whole thing is Invalid | ||||
174 | if (foundBracket && result == QValidator::Intermediate) | ||||
175 | return QValidator::Invalid; | ||||
176 | | ||||
177 | if (portSize < 2 || (portSize == 2 && portParts[1].isEmpty())) { | ||||
178 | return QValidator::Intermediate; | ||||
179 | } else { | ||||
180 | int portValue = portParts[1].toInt(); | ||||
181 | if (portValue > 65535) | ||||
182 | return QValidator::Invalid; | ||||
183 | } | ||||
184 | } | ||||
185 | return result; | ||||
85 | } | 186 | } |
unrelated changes