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
39class tst_QIpAddress : public QObject
40{
41 Q_OBJECT
42
43private 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
59struct 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};
88Q_DECLARE_METATYPE(Ip6)
89
90QT_BEGIN_NAMESPACE
91namespace 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}
108QT_END_NAMESPACE
109
110void 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
155void 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
175void 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
227void 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
247void 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
259void 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
275void 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
349void 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
367void 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
434void 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
451void 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
485void 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
504QTEST_APPLESS_MAIN(tst_QIpAddress)
505
506#include "tst_qipaddress.moc"
507

source code of qtbase/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp