1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 Intel Corporation. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | |
29 | #include <QtCore/QString> |
30 | #include <QtTest/QtTest> |
31 | #include <QtCore/private/qipaddress_p.h> |
32 | |
33 | #ifdef __GLIBC__ |
34 | #include <sys/socket.h> |
35 | #include <netinet/in.h> |
36 | #include <arpa/inet.h> |
37 | #endif |
38 | |
39 | class tst_QIpAddress : public QObject |
40 | { |
41 | Q_OBJECT |
42 | |
43 | private Q_SLOTS: |
44 | void parseIp4_data(); |
45 | void parseIp4(); |
46 | void invalidParseIp4_data(); |
47 | void invalidParseIp4(); |
48 | void ip4ToString_data(); |
49 | void ip4ToString(); |
50 | |
51 | void parseIp6_data(); |
52 | void parseIp6(); |
53 | void invalidParseIp6_data(); |
54 | void invalidParseIp6(); |
55 | void ip6ToString_data(); |
56 | void ip6ToString(); |
57 | }; |
58 | |
59 | struct Ip6 |
60 | { |
61 | QIPAddressUtils::IPv6Address u8; |
62 | Ip6() { *this = Ip6(0,0,0,0, 0,0,0,0); } |
63 | Ip6(quint16 p1, quint16 p2, quint16 p3, quint16 p4, |
64 | quint16 p5, quint16 p6, quint16 p7, quint16 p8) |
65 | { |
66 | u8[0] = p1 >> 8; |
67 | u8[2] = p2 >> 8; |
68 | u8[4] = p3 >> 8; |
69 | u8[6] = p4 >> 8; |
70 | u8[8] = p5 >> 8; |
71 | u8[10] = p6 >> 8; |
72 | u8[12] = p7 >> 8; |
73 | u8[14] = p8 >> 8; |
74 | |
75 | u8[1] = p1 & 0xff; |
76 | u8[3] = p2 & 0xff; |
77 | u8[5] = p3 & 0xff; |
78 | u8[7] = p4 & 0xff; |
79 | u8[9] = p5 & 0xff; |
80 | u8[11] = p6 & 0xff; |
81 | u8[13] = p7 & 0xff; |
82 | u8[15] = p8 & 0xff; |
83 | } |
84 | |
85 | bool operator==(const Ip6 &other) const |
86 | { return memcmp(s1: u8, s2: other.u8, n: sizeof u8) == 0; } |
87 | }; |
88 | Q_DECLARE_METATYPE(Ip6) |
89 | |
90 | QT_BEGIN_NAMESPACE |
91 | namespace QTest { |
92 | template<> |
93 | char *toString(const Ip6 &ip6) |
94 | { |
95 | char buf[sizeof "1111:2222:3333:4444:5555:6666:7777:8888" + 2]; |
96 | sprintf(s: buf, format: "%x:%x:%x:%x:%x:%x:%x:%x" , |
97 | ip6.u8[0] << 8 | ip6.u8[1], |
98 | ip6.u8[2] << 8 | ip6.u8[3], |
99 | ip6.u8[4] << 8 | ip6.u8[5], |
100 | ip6.u8[6] << 8 | ip6.u8[7], |
101 | ip6.u8[8] << 8 | ip6.u8[9], |
102 | ip6.u8[10] << 8 | ip6.u8[11], |
103 | ip6.u8[12] << 8 | ip6.u8[13], |
104 | ip6.u8[14] << 8 | ip6.u8[15]); |
105 | return qstrdup(buf); |
106 | } |
107 | } |
108 | QT_END_NAMESPACE |
109 | |
110 | void tst_QIpAddress::parseIp4_data() |
111 | { |
112 | QTest::addColumn<QString>(name: "data" ); |
113 | QTest::addColumn<QIPAddressUtils::IPv4Address>(name: "ip" ); |
114 | |
115 | // valid strings |
116 | QTest::newRow(dataTag: "0.0.0.0" ) << "0.0.0.0" << 0u; |
117 | QTest::newRow(dataTag: "10.0.0.1" ) << "10.0.0.1" << 0x0a000001u; |
118 | QTest::newRow(dataTag: "127.0.0.1" ) << "127.0.0.1" << 0x7f000001u; |
119 | QTest::newRow(dataTag: "172.16.0.1" ) << "172.16.0.1" << 0xac100001u; |
120 | QTest::newRow(dataTag: "172.16.16.1" ) << "172.16.16.1" << 0xac101001u; |
121 | QTest::newRow(dataTag: "172.16.16.16" ) << "172.16.16.16" << 0xac101010u; |
122 | QTest::newRow(dataTag: "192.168.0.1" ) << "192.168.0.1" << 0xc0a80001u; |
123 | QTest::newRow(dataTag: "192.168.16.1" ) << "192.168.16.1" << 0xc0a81001u; |
124 | QTest::newRow(dataTag: "192.168.16.16" ) << "192.168.16.16" << 0xc0a81010u; |
125 | QTest::newRow(dataTag: "192.168.192.1" ) << "192.168.192.1" << 0xc0a8c001u; |
126 | QTest::newRow(dataTag: "192.168.192.16" ) << "192.168.192.16" << 0xc0a8c010u; |
127 | QTest::newRow(dataTag: "192.168.192.255" ) << "192.168.192.255" << 0xc0a8c0ffu; |
128 | QTest::newRow(dataTag: "224.0.0.1" ) << "224.0.0.1" << 0xe0000001u; |
129 | QTest::newRow(dataTag: "239.255.255.255" ) << "239.255.255.255" << 0xefffffffu; |
130 | QTest::newRow(dataTag: "255.255.255.255" ) << "255.255.255.255" << uint(-1); |
131 | |
132 | // still valid but unusual |
133 | QTest::newRow(dataTag: "000.000.000.000" ) << "000.000.000.000" << 0u; |
134 | QTest::newRow(dataTag: "000001.000002.000000003.000000000004" ) << "000001.000002.000000003.000000000004" << 0x01020304u; |
135 | |
136 | // octals: |
137 | QTest::newRow(dataTag: "012.0250.0377.0377" ) << "012.0250.0377.0377" << 0x0aa8ffffu; |
138 | QTest::newRow(dataTag: "0000000000012.00000000000250.000000000000377.0000000000000000000000000000000000000377" ) |
139 | << "0000000000012.00000000000250.000000000000377.0000000000000000000000000000000000000377" << 0x0aa8ffffu; |
140 | |
141 | // hex: |
142 | QTest::newRow(dataTag: "0xa.0xa.0x7f.0xff" ) << "0xa.0xa.0x7f.0xff" << 0x0a0a7fffu; |
143 | |
144 | // dots missing, less than 255: |
145 | QTest::newRow(dataTag: "1.2.3" ) << "1.2.3" << 0x01020003u; |
146 | QTest::newRow(dataTag: "1.2" ) << "1.2" << 0x01000002u; |
147 | QTest::newRow(dataTag: "1" ) << "1" << 1u; |
148 | |
149 | // dots missing, more than 255, no overwrite |
150 | QTest::newRow(dataTag: "1.2.257" ) << "1.2.257" << 0x01020101u; |
151 | QTest::newRow(dataTag: "1.0x010101" ) << "1.0x010101" << 0x01010101u; |
152 | QTest::newRow(dataTag: "2130706433" ) << "2130706433" << 0x7f000001u; |
153 | } |
154 | |
155 | void tst_QIpAddress::parseIp4() |
156 | { |
157 | QFETCH(QString, data); |
158 | QFETCH(QIPAddressUtils::IPv4Address, ip); |
159 | |
160 | #ifdef __GLIBC__ |
161 | { |
162 | in_addr inet_result; |
163 | int inet_ok = inet_aton(cp: data.toLatin1(), inp: &inet_result); |
164 | QVERIFY(inet_ok); |
165 | QCOMPARE(ntohl(inet_result.s_addr), ip); |
166 | } |
167 | #endif |
168 | |
169 | QIPAddressUtils::IPv4Address result; |
170 | bool ok = QIPAddressUtils::parseIp4(address&: result, begin: data.constBegin(), end: data.constEnd()); |
171 | QVERIFY(ok); |
172 | QCOMPARE(result, ip); |
173 | } |
174 | |
175 | void tst_QIpAddress::invalidParseIp4_data() |
176 | { |
177 | QTest::addColumn<QString>(name: "data" ); |
178 | |
179 | // too many dots |
180 | QTest::newRow(dataTag: "." ) << "." ; |
181 | QTest::newRow(dataTag: ".." ) << ".." ; |
182 | QTest::newRow(dataTag: "..." ) << "..." ; |
183 | QTest::newRow(dataTag: "...." ) << "...." ; |
184 | QTest::newRow(dataTag: ".1.2.3" ) << ".1.2.3" ; |
185 | QTest::newRow(dataTag: "1." ) << "1." ; |
186 | QTest::newRow(dataTag: "1.2." ) << "1.2." ; |
187 | QTest::newRow(dataTag: "1.2.3." ) << "1.2.3." ; |
188 | QTest::newRow(dataTag: "1.2.3.4." ) << "1.2.3.4." ; |
189 | QTest::newRow(dataTag: "1.2.3..4" ) << "1.2.3..4" ; |
190 | |
191 | // octet more than 255 |
192 | QTest::newRow(dataTag: "2.2.2.257" ) << "2.2.2.257" ; |
193 | QTest::newRow(dataTag: "2.2.257.2" ) << "2.2.257.2" ; |
194 | QTest::newRow(dataTag: "2.257.2.2" ) << "2.257.2.2" ; |
195 | QTest::newRow(dataTag: "257.2.2.2" ) << "257.2.2.2" ; |
196 | |
197 | // number more than field available |
198 | QTest::newRow(dataTag: "2.2.0x01010101" ) << "2.2.0x01010101" ; |
199 | QTest::newRow(dataTag: "2.0x01010101" ) << "2.0x01010101" ; |
200 | QTest::newRow(dataTag: "4294967296" ) << "4294967296" ; |
201 | |
202 | // bad octals |
203 | QTest::newRow(dataTag: "09" ) << "09" ; |
204 | |
205 | // bad hex |
206 | QTest::newRow(dataTag: "0x1g" ) << "0x1g" ; |
207 | |
208 | // negative numbers |
209 | QTest::newRow(dataTag: "-1" ) << "-1" ; |
210 | QTest::newRow(dataTag: "-1.1" ) << "-1.1" ; |
211 | QTest::newRow(dataTag: "1.-1" ) << "1.-1" ; |
212 | QTest::newRow(dataTag: "1.1.1.-1" ) << "1.1.1.-1" ; |
213 | QTest::newRow(dataTag: "300-05" ) << "300-05" ; |
214 | QTest::newRow(dataTag: "127.-1" ) << "127.-1" ; |
215 | QTest::newRow(dataTag: "-127-10" ) << "-127-10" ; |
216 | QTest::newRow(dataTag: "198.-16" ) << "198-16" ; |
217 | QTest::newRow(dataTag: "-127.-0." ) << "-127.-0." ; |
218 | |
219 | // letters |
220 | QTest::newRow(dataTag: "abc" ) << "abc" ; |
221 | QTest::newRow(dataTag: "localhost" ) << "localhost" ; |
222 | QTest::newRow(dataTag: "1.2.3a.4" ) << "1.2.3a.4" ; |
223 | QTest::newRow(dataTag: "a.2.3.4" ) << "a.2.3.4" ; |
224 | QTest::newRow(dataTag: "1.2.3.4a" ) << "1.2.3.4a" ; |
225 | } |
226 | |
227 | void tst_QIpAddress::invalidParseIp4() |
228 | { |
229 | QFETCH(QString, data); |
230 | |
231 | #ifdef __GLIBC__ |
232 | { |
233 | in_addr inet_result; |
234 | int inet_ok = inet_aton(cp: data.toLatin1(), inp: &inet_result); |
235 | # ifdef Q_OS_DARWIN |
236 | QEXPECT_FAIL("4294967296" , "Mac's library does parse this one" , Continue); |
237 | # endif |
238 | QVERIFY(!inet_ok); |
239 | } |
240 | #endif |
241 | |
242 | QIPAddressUtils::IPv4Address result; |
243 | bool ok = QIPAddressUtils::parseIp4(address&: result, begin: data.constBegin(), end: data.constEnd()); |
244 | QVERIFY(!ok); |
245 | } |
246 | |
247 | void tst_QIpAddress::ip4ToString_data() |
248 | { |
249 | QTest::addColumn<QIPAddressUtils::IPv4Address>(name: "ip" ); |
250 | QTest::addColumn<QString>(name: "expected" ); |
251 | |
252 | QTest::newRow(dataTag: "0.0.0.0" ) << 0u << "0.0.0.0" ; |
253 | QTest::newRow(dataTag: "1.2.3.4" ) << 0x01020304u << "1.2.3.4" ; |
254 | QTest::newRow(dataTag: "127.0.0.1" ) << 0x7f000001u << "127.0.0.1" ; |
255 | QTest::newRow(dataTag: "111.222.33.44" ) << 0x6fde212cu << "111.222.33.44" ; |
256 | QTest::newRow(dataTag: "255.255.255.255" ) << 0xffffffffu << "255.255.255.255" ; |
257 | } |
258 | |
259 | void tst_QIpAddress::ip4ToString() |
260 | { |
261 | QFETCH(QIPAddressUtils::IPv4Address, ip); |
262 | QFETCH(QString, expected); |
263 | |
264 | #ifdef __GLIBC__ |
265 | in_addr inet_ip; |
266 | inet_ip.s_addr = htonl(hostlong: ip); |
267 | QCOMPARE(QString(inet_ntoa(inet_ip)), expected); |
268 | #endif |
269 | |
270 | QString result; |
271 | QIPAddressUtils::toString(appendTo&: result, address: ip); |
272 | QCOMPARE(result, expected); |
273 | } |
274 | |
275 | void tst_QIpAddress::parseIp6_data() |
276 | { |
277 | qRegisterMetaType<Ip6>(); |
278 | QTest::addColumn<QString>(name: "address" ); |
279 | QTest::addColumn<Ip6>(name: "expected" ); |
280 | |
281 | // 7 colons, no :: |
282 | QTest::newRow(dataTag: "0:0:0:0:0:0:0:0" ) << "0:0:0:0:0:0:0:0" << Ip6(0,0,0,0,0,0,0,0); |
283 | QTest::newRow(dataTag: "0:0:0:0:0:0:0:1" ) << "0:0:0:0:0:0:0:1" << Ip6(0,0,0,0,0,0,0,1); |
284 | QTest::newRow(dataTag: "0:0:0:0:0:0:1:1" ) << "0:0:0:0:0:0:1:1" << Ip6(0,0,0,0,0,0,1,1); |
285 | QTest::newRow(dataTag: "0:0:0:0:0:0:0:103" ) << "0:0:0:0:0:0:0:103" << Ip6(0,0,0,0,0,0,0,0x103); |
286 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:8" ) << "1:2:3:4:5:6:7:8" << Ip6(1,2,3,4,5,6,7,8); |
287 | QTest::newRow(dataTag: "ffee:ddcc:bbaa:9988:7766:5544:3322:1100" ) |
288 | << "ffee:ddcc:bbaa:9988:7766:5544:3322:1100" |
289 | << Ip6(0xffee, 0xddcc, 0xbbaa, 0x9988, 0x7766, 0x5544, 0x3322, 0x1100); |
290 | |
291 | // double-colon |
292 | QTest::newRow(dataTag: "::1:2:3:4:5:6:7" ) << "::1:2:3:4:5:6:7" << Ip6(0,1,2,3,4,5,6,7); |
293 | QTest::newRow(dataTag: "1:2:3:4:5:6:7::" ) << "1:2:3:4:5:6:7::" << Ip6(1,2,3,4,5,6,7,0); |
294 | |
295 | QTest::newRow(dataTag: "1::2:3:4:5:6:7" ) << "1::2:3:4:5:6:7" << Ip6(1,0,2,3,4,5,6,7); |
296 | QTest::newRow(dataTag: "1:2::3:4:5:6:7" ) << "1:2::3:4:5:6:7" << Ip6(1,2,0,3,4,5,6,7); |
297 | QTest::newRow(dataTag: "1:2:3::4:5:6:7" ) << "1:2:3::4:5:6:7" << Ip6(1,2,3,0,4,5,6,7); |
298 | QTest::newRow(dataTag: "1:2:3:4::5:6:7" ) << "1:2:3:4::5:6:7" << Ip6(1,2,3,4,0,5,6,7); |
299 | QTest::newRow(dataTag: "1:2:3:4:5::6:7" ) << "1:2:3:4:5::6:7" << Ip6(1,2,3,4,5,0,6,7); |
300 | QTest::newRow(dataTag: "1:2:3:4:5:6::7" ) << "1:2:3:4:5:6::7" << Ip6(1,2,3,4,5,6,0,7); |
301 | |
302 | QTest::newRow(dataTag: "::1:2:3:4:5:6" ) << "::1:2:3:4:5:6" << Ip6(0,0,1,2,3,4,5,6); |
303 | QTest::newRow(dataTag: "1:2:3:4:5:6::" ) << "1:2:3:4:5:6::" << Ip6(1,2,3,4,5,6,0,0); |
304 | |
305 | QTest::newRow(dataTag: "1::2:3:4:5:6" ) << "1::2:3:4:5:6" << Ip6(1,0,0,2,3,4,5,6); |
306 | QTest::newRow(dataTag: "1:2::3:4:5:6" ) << "1:2::3:4:5:6" << Ip6(1,2,0,0,3,4,5,6); |
307 | QTest::newRow(dataTag: "1:2:3::4:5:6" ) << "1:2:3::4:5:6" << Ip6(1,2,3,0,0,4,5,6); |
308 | QTest::newRow(dataTag: "1:2:3:4::5:6" ) << "1:2:3:4::5:6" << Ip6(1,2,3,4,0,0,5,6); |
309 | QTest::newRow(dataTag: "1:2:3:4:5::6" ) << "1:2:3:4:5::6" << Ip6(1,2,3,4,5,0,0,6); |
310 | |
311 | QTest::newRow(dataTag: "::1:2:3:4:5" ) << "::1:2:3:4:5" << Ip6(0,0,0,1,2,3,4,5); |
312 | QTest::newRow(dataTag: "1:2:3:4:5::" ) << "1:2:3:4:5::" << Ip6(1,2,3,4,5,0,0,0); |
313 | |
314 | QTest::newRow(dataTag: "1::2:3:4:5" ) << "1::2:3:4:5" << Ip6(1,0,0,0,2,3,4,5); |
315 | QTest::newRow(dataTag: "1:2::3:4:5" ) << "1:2::3:4:5" << Ip6(1,2,0,0,0,3,4,5); |
316 | QTest::newRow(dataTag: "1:2:3::4:5" ) << "1:2:3::4:5" << Ip6(1,2,3,0,0,0,4,5); |
317 | QTest::newRow(dataTag: "1:2:3:4::5" ) << "1:2:3:4::5" << Ip6(1,2,3,4,0,0,0,5); |
318 | |
319 | QTest::newRow(dataTag: "::1:2:3:4" ) << "::1:2:3:4" << Ip6(0,0,0,0,1,2,3,4); |
320 | QTest::newRow(dataTag: "1:2:3:4::" ) << "1:2:3:4::" << Ip6(1,2,3,4,0,0,0,0); |
321 | |
322 | QTest::newRow(dataTag: "1::2:3:4" ) << "1::2:3:4" << Ip6(1,0,0,0,0,2,3,4); |
323 | QTest::newRow(dataTag: "1:2::3:4" ) << "1:2::3:4" << Ip6(1,2,0,0,0,0,3,4); |
324 | QTest::newRow(dataTag: "1:2:3::4" ) << "1:2:3::4" << Ip6(1,2,3,0,0,0,0,4); |
325 | |
326 | QTest::newRow(dataTag: "::1:2:3" ) << "::1:2:3" << Ip6(0,0,0,0,0,1,2,3); |
327 | QTest::newRow(dataTag: "1:2:3::" ) << "1:2:3::" << Ip6(1,2,3,0,0,0,0,0); |
328 | |
329 | QTest::newRow(dataTag: "1::2:3" ) << "1::2:3" << Ip6(1,0,0,0,0,0,2,3); |
330 | QTest::newRow(dataTag: "1:2::3" ) << "1:2::3" << Ip6(1,2,0,0,0,0,0,3); |
331 | |
332 | QTest::newRow(dataTag: "::1:2" ) << "::1:2" << Ip6(0,0,0,0,0,0,1,2); |
333 | QTest::newRow(dataTag: "1:2::" ) << "1:2::" << Ip6(1,2,0,0,0,0,0,0); |
334 | |
335 | QTest::newRow(dataTag: "1::2" ) << "1::2" << Ip6(1,0,0,0,0,0,0,2); |
336 | |
337 | QTest::newRow(dataTag: "::1" ) << "::1" << Ip6(0,0,0,0,0,0,0,1); |
338 | QTest::newRow(dataTag: "1::" ) << "1::" << Ip6(1,0,0,0,0,0,0,0); |
339 | |
340 | QTest::newRow(dataTag: "::" ) << "::" << Ip6(0,0,0,0,0,0,0,0); |
341 | |
342 | // embedded IPv4 |
343 | QTest::newRow(dataTag: "1:2:3:4:5:6:10.0.16.1" ) << "1:2:3:4:5:6:10.0.16.1" << Ip6(1,2,3,4,5,6,0xa00,0x1001); |
344 | QTest::newRow(dataTag: "1::10.0.16.1" ) << "1::10.0.16.1" << Ip6(1,0,0,0,0,0,0xa00,0x1001); |
345 | QTest::newRow(dataTag: "::10.0.16.1" ) << "::10.0.16.1" << Ip6(0,0,0,0,0,0,0xa00,0x1001); |
346 | QTest::newRow(dataTag: "::0.0.0.0" ) << "::0.0.0.0" << Ip6(0,0,0,0,0,0,0,0); |
347 | } |
348 | |
349 | void tst_QIpAddress::parseIp6() |
350 | { |
351 | QFETCH(QString, address); |
352 | QFETCH(Ip6, expected); |
353 | |
354 | #if defined(__GLIBC__) && defined(AF_INET6) |
355 | Ip6 inet_result; |
356 | bool inet_ok = inet_pton(AF_INET6, cp: address.toLatin1(), buf: &inet_result.u8); |
357 | QVERIFY(inet_ok); |
358 | QCOMPARE(inet_result, expected); |
359 | #endif |
360 | |
361 | Ip6 result; |
362 | bool ok = QIPAddressUtils::parseIp6(address&: result.u8, begin: address.constBegin(), end: address.constEnd()) == 0; |
363 | QVERIFY(ok); |
364 | QCOMPARE(result, expected); |
365 | } |
366 | |
367 | void tst_QIpAddress::invalidParseIp6_data() |
368 | { |
369 | QTest::addColumn<QString>(name: "address" ); |
370 | |
371 | // too many colons |
372 | QTest::newRow(dataTag: "0:0:0:0::0:0:0:0" ) << "0:0:0:0::0:0:0:0" ; |
373 | QTest::newRow(dataTag: "0:::" ) << "0:::" ; QTest::newRow(dataTag: ":::0" ) << ":::0" ; |
374 | QTest::newRow(dataTag: "16:::::::::::::::::::::::" ) << "16:::::::::::::::::::::::" ; |
375 | |
376 | // non-hex |
377 | QTest::newRow(dataTag: "a:b:c:d:e:f:g:h" ) << "a:b:c:d:e:f:g:h" ; |
378 | |
379 | // too big number |
380 | QTest::newRow(dataTag: "0:0:0:0:0:0:0:10103" ) << "0:0:0:0:0:0:0:10103" ; |
381 | |
382 | // too many zeroes |
383 | QTest::newRow(dataTag: "0:0:0:0:0:0:0:00103" ) << "0:0:0:0:0:0:0:00103" ; |
384 | |
385 | // too short |
386 | QTest::newRow(dataTag: "0:0:0:0:0:0:0:" ) << "0:0:0:0:0:0:0:" ; |
387 | QTest::newRow(dataTag: "0:0:0:0:0:0:0" ) << "0:0:0:0:0:0:0" ; |
388 | QTest::newRow(dataTag: "0:0:0:0:0:0:" ) << "0:0:0:0:0:0:" ; |
389 | QTest::newRow(dataTag: "0:0:0:0:0:0" ) << "0:0:0:0:0:0" ; |
390 | QTest::newRow(dataTag: "0:0:0:0:0:" ) << "0:0:0:0:0:" ; |
391 | QTest::newRow(dataTag: "0:0:0:0:0" ) << "0:0:0:0:0" ; |
392 | QTest::newRow(dataTag: "0:0:0:0:" ) << "0:0:0:0:" ; |
393 | QTest::newRow(dataTag: "0:0:0:0" ) << "0:0:0:0" ; |
394 | QTest::newRow(dataTag: "0:0:0:" ) << "0:0:0:" ; |
395 | QTest::newRow(dataTag: "0:0:0" ) << "0:0:0" ; |
396 | QTest::newRow(dataTag: "0:0:" ) << "0:0:" ; |
397 | QTest::newRow(dataTag: "0:0" ) << "0:0" ; |
398 | QTest::newRow(dataTag: "0:" ) << "0:" ; |
399 | QTest::newRow(dataTag: "0" ) << "0" ; |
400 | QTest::newRow(dataTag: ":0" ) << ":0" ; |
401 | QTest::newRow(dataTag: ":0:0" ) << ":0:0" ; |
402 | QTest::newRow(dataTag: ":0:0:0" ) << ":0:0:0" ; |
403 | QTest::newRow(dataTag: ":0:0:0:0" ) << ":0:0:0:0" ; |
404 | QTest::newRow(dataTag: ":0:0:0:0:0" ) << ":0:0:0:0:0" ; |
405 | QTest::newRow(dataTag: ":0:0:0:0:0:0" ) << ":0:0:0:0:0:0" ; |
406 | QTest::newRow(dataTag: ":0:0:0:0:0:0:0" ) << ":0:0:0:0:0:0:0" ; |
407 | |
408 | // IPv4 |
409 | QTest::newRow(dataTag: "1.2.3.4" ) << "1.2.3.4" ; |
410 | |
411 | // embedded IPv4 in the wrong position |
412 | QTest::newRow(dataTag: "1.2.3.4::" ) << "1.2.3.4::" ; |
413 | QTest::newRow(dataTag: "f:1.2.3.4::" ) << "f:1.2.3.4::" ; |
414 | QTest::newRow(dataTag: "f:e:d:c:b:1.2.3.4:0" ) << "f:e:d:c:b:1.2.3.4:0" ; |
415 | |
416 | // bad embedded IPv4 |
417 | QTest::newRow(dataTag: "::1.2.3" ) << "::1.2.3" ; |
418 | QTest::newRow(dataTag: "::1.2.257" ) << "::1.2.257" ; |
419 | QTest::newRow(dataTag: "::1.2" ) << "::1.2" ; |
420 | QTest::newRow(dataTag: "::0250.0x10101" ) << "::0250.0x10101" ; |
421 | QTest::newRow(dataTag: "::1.2.3.0250" ) << "::1.2.3.0250" ; |
422 | QTest::newRow(dataTag: "::1.2.3.0xff" ) << "::1.2.3.0xff" ; |
423 | QTest::newRow(dataTag: "::1.2.3.07" ) << "::1.2.3.07" ; |
424 | QTest::newRow(dataTag: "::1.2.3.010" ) << "::1.2.3.010" ; |
425 | |
426 | // separated by something else |
427 | QTest::newRow(dataTag: "1.2.3.4.5.6.7.8" ) << "1.2.3.4.5.6.7.8" ; |
428 | QTest::newRow(dataTag: "1,2,3,4,5,6,7,8" ) << "1,2,3,4,5,6,7,8" ; |
429 | QTest::newRow(dataTag: "1..2" ) << "1..2" ; |
430 | QTest::newRow(dataTag: "1:.2" ) << "1:.2" ; |
431 | QTest::newRow(dataTag: "1.:2" ) << "1.:2" ; |
432 | } |
433 | |
434 | void tst_QIpAddress::invalidParseIp6() |
435 | { |
436 | QFETCH(QString, address); |
437 | |
438 | #if defined(__GLIBC__) && defined(AF_INET6) |
439 | Ip6 inet_result; |
440 | bool inet_ok = inet_pton(AF_INET6, cp: address.toLatin1(), buf: &inet_result.u8); |
441 | if (__GLIBC_MINOR__ < 26) |
442 | QEXPECT_FAIL("0:0:0:0:0:0:0:00103" , "Bug fixed in glibc 2.26" , Continue); |
443 | QVERIFY(!inet_ok); |
444 | #endif |
445 | |
446 | Ip6 result; |
447 | bool ok = QIPAddressUtils::parseIp6(address&: result.u8, begin: address.constBegin(), end: address.constEnd()) == 0; |
448 | QVERIFY(!ok); |
449 | } |
450 | |
451 | void tst_QIpAddress::ip6ToString_data() |
452 | { |
453 | qRegisterMetaType<Ip6>(); |
454 | QTest::addColumn<Ip6>(name: "ip" ); |
455 | QTest::addColumn<QString>(name: "expected" ); |
456 | |
457 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:8" ) << Ip6(1,2,3,4,5,6,7,8) << "1:2:3:4:5:6:7:8" ; |
458 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:88" ) << Ip6(1,2,3,4,5,6,7,0x88) << "1:2:3:4:5:6:7:88" ; |
459 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:888" ) << Ip6(1,2,3,4,5,6,7,0x888) << "1:2:3:4:5:6:7:888" ; |
460 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:8888" ) << Ip6(1,2,3,4,5,6,7,0x8888) << "1:2:3:4:5:6:7:8888" ; |
461 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:8880" ) << Ip6(1,2,3,4,5,6,7,0x8880) << "1:2:3:4:5:6:7:8880" ; |
462 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:8808" ) << Ip6(1,2,3,4,5,6,7,0x8808) << "1:2:3:4:5:6:7:8808" ; |
463 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:8088" ) << Ip6(1,2,3,4,5,6,7,0x8088) << "1:2:3:4:5:6:7:8088" ; |
464 | |
465 | QTest::newRow(dataTag: "1:2:3:4:5:6:7:0" ) << Ip6(1,2,3,4,5,6,7,0) << "1:2:3:4:5:6:7:0" ; |
466 | QTest::newRow(dataTag: "0:1:2:3:4:5:6:7" ) << Ip6(0,1,2,3,4,5,6,7) << "0:1:2:3:4:5:6:7" ; |
467 | |
468 | QTest::newRow(dataTag: "1:2:3:4:5:6::" ) << Ip6(1,2,3,4,5,6,0,0) << "1:2:3:4:5:6::" ; |
469 | QTest::newRow(dataTag: "::1:2:3:4:5:6" ) << Ip6(0,0,1,2,3,4,5,6) << "::1:2:3:4:5:6" ; |
470 | QTest::newRow(dataTag: "1:0:0:2::3" ) << Ip6(1,0,0,2,0,0,0,3) << "1:0:0:2::3" ; |
471 | QTest::newRow(dataTag: "1:::2:0:0:3" ) << Ip6(1,0,0,0,2,0,0,3) << "1::2:0:0:3" ; |
472 | QTest::newRow(dataTag: "1::2:0:0:0" ) << Ip6(1,0,0,0,2,0,0,0) << "1::2:0:0:0" ; |
473 | QTest::newRow(dataTag: "0:0:0:1::" ) << Ip6(0,0,0,1,0,0,0,0) << "0:0:0:1::" ; |
474 | QTest::newRow(dataTag: "::1:0:0:0" ) << Ip6(0,0,0,0,1,0,0,0) << "::1:0:0:0" ; |
475 | QTest::newRow(dataTag: "ff02::1" ) << Ip6(0xff02,0,0,0,0,0,0,1) << "ff02::1" ; |
476 | QTest::newRow(dataTag: "1::1" ) << Ip6(1,0,0,0,0,0,0,1) << "1::1" ; |
477 | QTest::newRow(dataTag: "::1" ) << Ip6(0,0,0,0,0,0,0,1) << "::1" ; |
478 | QTest::newRow(dataTag: "1::" ) << Ip6(1,0,0,0,0,0,0,0) << "1::" ; |
479 | QTest::newRow(dataTag: "::" ) << Ip6(0,0,0,0,0,0,0,0) << "::" ; |
480 | |
481 | QTest::newRow(dataTag: "::1.2.3.4" ) << Ip6(0,0,0,0,0,0,0x102,0x304) << "::1.2.3.4" ; |
482 | QTest::newRow(dataTag: "::ffff:1.2.3.4" ) << Ip6(0,0,0,0,0,0xffff,0x102,0x304) << "::ffff:1.2.3.4" ; |
483 | } |
484 | |
485 | void tst_QIpAddress::ip6ToString() |
486 | { |
487 | QFETCH(Ip6, ip); |
488 | QFETCH(QString, expected); |
489 | |
490 | #if defined(__GLIBC__) && defined(AF_INET6) |
491 | { |
492 | char buf[INET6_ADDRSTRLEN]; |
493 | bool ok = inet_ntop(AF_INET6, cp: ip.u8, buf: buf, len: sizeof buf) != 0; |
494 | QVERIFY(ok); |
495 | QCOMPARE(QString(buf), expected); |
496 | } |
497 | #endif |
498 | |
499 | QString result; |
500 | QIPAddressUtils::toString(appendTo&: result, address: ip.u8); |
501 | QCOMPARE(result, expected); |
502 | } |
503 | |
504 | QTEST_APPLESS_MAIN(tst_QIpAddress) |
505 | |
506 | #include "tst_qipaddress.moc" |
507 | |