1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Copyright (C) 2016 Intel Corporation. |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the test suite of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
22 | ** included in the packaging of this file. Please review the following |
23 | ** information to ensure the GNU General Public License requirements will |
24 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
25 | ** |
26 | ** $QT_END_LICENSE$ |
27 | ** |
28 | ****************************************************************************/ |
29 | |
30 | #include <qhostaddress.h> |
31 | #include <private/qhostaddress_p.h> |
32 | #include <qcoreapplication.h> |
33 | #include <QtTest/QtTest> |
34 | #include <qplatformdefs.h> |
35 | #include <qdebug.h> |
36 | #include <qhash.h> |
37 | #include <qbytearray.h> |
38 | #include <qdatastream.h> |
39 | #ifdef Q_OS_WIN |
40 | # include <qt_windows.h> |
41 | # if defined(Q_OS_WINRT) |
42 | # include <winsock2.h> |
43 | # endif |
44 | #endif |
45 | |
46 | #ifdef Q_OS_ANDROID |
47 | # include <netinet/in.h> |
48 | #endif |
49 | |
50 | Q_DECLARE_METATYPE(AddressClassification) |
51 | Q_DECLARE_METATYPE(QHostAddress::SpecialAddress) |
52 | |
53 | class tst_QHostAddress : public QObject |
54 | { |
55 | Q_OBJECT |
56 | |
57 | public: |
58 | tst_QHostAddress(); |
59 | |
60 | private slots: |
61 | void constructor_QString_data(); |
62 | void constructor_QString(); |
63 | void setAddress_QString_data(); |
64 | void setAddress_QString(); |
65 | void specialAddresses_data(); |
66 | void specialAddresses(); |
67 | void compare_data(); |
68 | void compare(); |
69 | void isEqual_data(); |
70 | void isEqual(); |
71 | void assignment(); |
72 | void scopeId(); |
73 | void hashKey(); |
74 | void streaming_data(); |
75 | void streaming(); |
76 | void parseSubnet_data(); |
77 | void parseSubnet(); |
78 | void isInSubnet_data(); |
79 | void isInSubnet(); |
80 | void classification_data(); |
81 | void classification(); |
82 | void convertv4v6_data(); |
83 | void convertv4v6(); |
84 | }; |
85 | |
86 | Q_DECLARE_METATYPE(QHostAddress) |
87 | |
88 | tst_QHostAddress::tst_QHostAddress() |
89 | { |
90 | qRegisterMetaType<QHostAddress>(typeName: "QHostAddress"); |
91 | } |
92 | |
93 | void tst_QHostAddress::constructor_QString_data() |
94 | { |
95 | setAddress_QString_data(); |
96 | } |
97 | |
98 | void tst_QHostAddress::constructor_QString() |
99 | { |
100 | QFETCH(QString, address); |
101 | QFETCH(bool, ok); |
102 | QFETCH(int, protocol); |
103 | |
104 | QHostAddress hostAddr(address); |
105 | |
106 | if (address == "0.0.0.0"|| address == "::") { |
107 | QVERIFY(ok); |
108 | } else { |
109 | QVERIFY(hostAddr.isNull() != ok); |
110 | } |
111 | |
112 | if (ok) |
113 | QTEST(hostAddr.toString(), "resAddr"); |
114 | |
115 | if ( protocol == 4 ) { |
116 | QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv4Protocol || hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol ); |
117 | QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv6Protocol ); |
118 | } else if ( protocol == 6 ) { |
119 | QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv4Protocol && hostAddr.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol ); |
120 | QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv6Protocol ); |
121 | } else { |
122 | QVERIFY( hostAddr.isNull() ); |
123 | QVERIFY( hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol ); |
124 | } |
125 | } |
126 | |
127 | void tst_QHostAddress::setAddress_QString_data() |
128 | { |
129 | QTest::addColumn<QString>(name: "address"); |
130 | QTest::addColumn<bool>(name: "ok"); |
131 | QTest::addColumn<QString>(name: "resAddr"); |
132 | QTest::addColumn<int>(name: "protocol"); // 4: IPv4, 6: IPv6, other: undefined |
133 | |
134 | //next we fill it with data |
135 | QTest::newRow(dataTag: "ip4_00") << QString( "127.0.0.1") << true << QString( "127.0.0.1") << 4; |
136 | QTest::newRow(dataTag: "ip4_01") << QString( "255.3.2.1") << true << QString( "255.3.2.1") << 4; |
137 | QTest::newRow(dataTag: "ip4_03") << QString( " 255.3.2.1") << true << QString( "255.3.2.1") << 4; |
138 | QTest::newRow(dataTag: "ip4_04") << QString( "255.3.2.1\r ") << true << QString( "255.3.2.1") << 4; |
139 | QTest::newRow(dataTag: "ip4_05") << QString( "0.0.0.0") << true << QString( "0.0.0.0") << 4; |
140 | QTest::newRow(dataTag: "ip4_06") << QString( "123.0.0") << true << QString( "123.0.0.0") << 4; |
141 | |
142 | // for the format of IPv6 addresses see also RFC 5952 |
143 | // rule 4.1: Leading zeros MUST be suppressed |
144 | // rule 4.2.1: Shorten as Much as Possible |
145 | // rule 4.2.2: The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field. |
146 | // rule 4.2.3: the longest run of consecutive 16-bit 0 fields MUST be shortened |
147 | // When the length of the consecutive 16-bit 0 fields, the first sequence |
148 | // of zero bits MUST be shortened |
149 | // rule 4.3: The characters "a", "b", "c", "d", "e", and "f" in an IPv6 address |
150 | // MUST be represented in lowercase |
151 | QTest::newRow(dataTag: "ip6_00") << QString( "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << true << QString( "fedc:ba98:7654:3210:fedc:ba98:7654:3210") << 6; // 4.3 |
152 | QTest::newRow(dataTag: "ip6_01") << QString( "1080:0000:0000:0000:0008:0800:200C:417A") << true << QString( "1080::8:800:200c:417a") << 6; // 4.1, 4.2.1 |
153 | QTest::newRow(dataTag: "ip6_02") << QString( "1080:0:0:0:8:800:200C:417A") << true << QString( "1080::8:800:200c:417a") << 6; |
154 | QTest::newRow(dataTag: "ip6_03") << QString( "1080::8:800:200C:417A") << true << QString( "1080::8:800:200c:417a") << 6; |
155 | QTest::newRow(dataTag: "ip6_04") << QString( "FF01::43") << true << QString( "ff01::43") << 6; |
156 | QTest::newRow(dataTag: "ip6_05") << QString( "::1") << true << QString( "::1") << 6; |
157 | QTest::newRow(dataTag: "ip6_06") << QString( "1::") << true << QString( "1::") << 6; |
158 | QTest::newRow(dataTag: "ip6_07") << QString( "::") << true << QString( "::") << 6; |
159 | QTest::newRow(dataTag: "ip6_08") << QString( "0:0:0:0:0:0:13.1.68.3") << true << QString( "::13.1.68.3") << 6; |
160 | QTest::newRow(dataTag: "ip6_09") << QString( "::13.1.68.3") << true << QString( "::13.1.68.3") << 6; |
161 | QTest::newRow(dataTag: "ip6_10") << QString( "0:0:0:0:0:FFFF:129.144.52.38") << true << QString( "::ffff:129.144.52.38") << 6; |
162 | QTest::newRow(dataTag: "ip6_11") << QString( "::FFFF:129.144.52.38") << true << QString( "::ffff:129.144.52.38") << 6; |
163 | QTest::newRow(dataTag: "ip6_12") << QString( "1::FFFF:129.144.52.38") << true << QString( "1::ffff:8190:3426") << 6; |
164 | QTest::newRow(dataTag: "ip6_13") << QString( "A:B::D:E") << true << QString( "a:b::d:e") << 6; |
165 | QTest::newRow(dataTag: "ip6_14") << QString( "1080:0:1:0:8:800:200C:417A") << true << QString( "1080:0:1:0:8:800:200c:417a") << 6; // 4.2.2 |
166 | QTest::newRow(dataTag: "ip6_15") << QString( "1080:0:1:0:8:800:200C:0") << true << QString( "1080:0:1:0:8:800:200c:0") << 6; |
167 | QTest::newRow(dataTag: "ip6_16") << QString( "1080:0:1:0:8:800:0:0") << true << QString( "1080:0:1:0:8:800::") << 6; |
168 | QTest::newRow(dataTag: "ip6_17a") << QString( "1080:0:0:8:800:0:0:0") << true << QString( "1080:0:0:8:800::") << 6; // 4.2.3a |
169 | QTest::newRow(dataTag: "ip6_17b") << QString( "1080:0:0:0:8:0:0:0") << true << QString( "1080::8:0:0:0") << 6; // 4.2.3b |
170 | QTest::newRow(dataTag: "ip6_18") << QString( "0:1:1:1:8:800:0:0") << true << QString( "0:1:1:1:8:800::") << 6; |
171 | QTest::newRow(dataTag: "ip6_19") << QString( "0:1:1:1:8:800:0:1") << true << QString( "0:1:1:1:8:800:0:1") << 6; |
172 | |
173 | QTest::newRow(dataTag: "error_00") << QString( "foobarcom") << false << QString() << 0; |
174 | QTest::newRow(dataTag: "error_01") << QString( "foo.bar.com") << false << QString() << 0; |
175 | QTest::newRow(dataTag: "error_02") << QString( "") << false << QString() << 0; |
176 | QTest::newRow(dataTag: "error_03") << QString() << false << QString() << 0; |
177 | QTest::newRow(dataTag: "error_04") << QString( " \t\r") << false << QString() << 0; |
178 | |
179 | QTest::newRow(dataTag: "error_ip4_00") << QString( "256.9.9.9") << false << QString() << 0; |
180 | QTest::newRow(dataTag: "error_ip4_01") << QString( "-1.9.9.9") << false << QString() << 0; |
181 | //QTest::newRow("error_ip4_02") << QString("123.0.0") << false << QString() << 0; // no longer invalid in Qt5 |
182 | QTest::newRow(dataTag: "error_ip4_02") << QString( "123.0.0.") << false << QString() << 0; |
183 | QTest::newRow(dataTag: "error_ip4_03") << QString( "123.0.0.0.0") << false << QString() << 0; |
184 | QTest::newRow(dataTag: "error_ip4_04") << QString( "255.2 3.2.1") << false << QString() << 0; |
185 | |
186 | QTest::newRow(dataTag: "error_ip6_00") << QString( ":") << false << QString() << 0; |
187 | QTest::newRow(dataTag: "error_ip6_01") << QString( ":::") << false << QString() << 0; |
188 | QTest::newRow(dataTag: "error_ip6_02") << QString( "::AAAA:") << false << QString() << 0; |
189 | QTest::newRow(dataTag: "error_ip6_03") << QString( ":AAAA::") << false << QString() << 0; |
190 | QTest::newRow(dataTag: "error_ip6_04") << QString( "FFFF:::129.144.52.38") << false << QString() << 0; |
191 | QTest::newRow(dataTag: "error_ip6_05") << QString( "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210:1234") << false << QString() << 0; |
192 | QTest::newRow(dataTag: "error_ip6_06") << QString( "129.144.52.38::") << false << QString() << 0; |
193 | QTest::newRow(dataTag: "error_ip6_07") << QString( "::129.144.52.38:129.144.52.38") << false << QString() << 0; |
194 | QTest::newRow(dataTag: "error_ip6_08") << QString( ":::129.144.52.38") << false << QString() << 0; |
195 | QTest::newRow(dataTag: "error_ip6_09") << QString( "1FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << false << QString() << 0; |
196 | QTest::newRow(dataTag: "error_ip6_10") << QString( "::FFFFFFFF") << false << QString() << 0; |
197 | QTest::newRow(dataTag: "error_ip6_11") << QString( "::EFGH") << false << QString() << 0; |
198 | QTest::newRow(dataTag: "error_ip6_12") << QString( "ABCD:ABCD:ABCD") << false << QString() << 0; |
199 | QTest::newRow(dataTag: "error_ip6_13") << QString( "::ABCD:ABCD::") << false << QString() << 0; |
200 | QTest::newRow(dataTag: "error_ip6_14") << QString( "1::2::3") << false << QString() << 0; |
201 | QTest::newRow(dataTag: "error_ip6_15") << QString( "1:2:::") << false << QString() << 0; |
202 | QTest::newRow(dataTag: "error_ip6_16") << QString( ":::1:2") << false << QString() << 0; |
203 | QTest::newRow(dataTag: "error_ip6_17") << QString( "1:::2") << false << QString() << 0; |
204 | QTest::newRow(dataTag: "error_ip6_18") << QString( "FEDC::7654:3210:FEDC:BA98::3210") << false << QString() << 0; |
205 | QTest::newRow(dataTag: "error_ip6_19") << QString( "ABCD:ABCD:ABCD:1.2.3.4") << false << QString() << 0; |
206 | QTest::newRow(dataTag: "error_ip6_20") << QString( "ABCD::ABCD::ABCD:1.2.3.4") << false << QString() << 0; |
207 | |
208 | } |
209 | |
210 | void tst_QHostAddress::setAddress_QString() |
211 | { |
212 | QFETCH(QString, address); |
213 | QFETCH(bool, ok); |
214 | QFETCH(int, protocol); |
215 | |
216 | QHostAddress hostAddr; |
217 | QCOMPARE(hostAddr.setAddress(address), ok); |
218 | |
219 | if (ok) |
220 | QTEST(hostAddr.toString(), "resAddr"); |
221 | |
222 | if ( protocol == 4 ) { |
223 | QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv4Protocol || hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol ); |
224 | QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv6Protocol ); |
225 | } else if ( protocol == 6 ) { |
226 | QVERIFY( hostAddr.protocol() != QAbstractSocket::IPv4Protocol && hostAddr.protocol() != QAbstractSocket::UnknownNetworkLayerProtocol ); |
227 | QVERIFY( hostAddr.protocol() == QAbstractSocket::IPv6Protocol ); |
228 | } else { |
229 | QVERIFY( hostAddr.isNull() ); |
230 | QVERIFY( hostAddr.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol ); |
231 | } |
232 | } |
233 | |
234 | void tst_QHostAddress::specialAddresses_data() |
235 | { |
236 | QTest::addColumn<QString>(name: "text"); |
237 | QTest::addColumn<QHostAddress::SpecialAddress>(name: "address"); |
238 | QTest::addColumn<bool>(name: "result"); |
239 | |
240 | QTest::newRow(dataTag: "localhost_1") << QString( "127.0.0.1") << QHostAddress::LocalHost << true; |
241 | QTest::newRow(dataTag: "localhost_2") << QString( "127.0.0.2") << QHostAddress::LocalHost << false; |
242 | QTest::newRow(dataTag: "localhost_3") << QString( "127.0.0.2") << QHostAddress::LocalHostIPv6 << false; |
243 | |
244 | QTest::newRow(dataTag: "localhost_ipv6_4") << QString( "::1") << QHostAddress::LocalHostIPv6 << true; |
245 | QTest::newRow(dataTag: "localhost_ipv6_5") << QString( "::2") << QHostAddress::LocalHostIPv6 << false; |
246 | QTest::newRow(dataTag: "localhost_ipv6_6") << QString( "::1") << QHostAddress::LocalHost << false; |
247 | |
248 | QTest::newRow(dataTag: "null_1") << QString( "") << QHostAddress::Null << true; |
249 | QTest::newRow(dataTag: "null_2") << QString( "bjarne") << QHostAddress::Null << true; |
250 | |
251 | QTest::newRow(dataTag: "compare_from_null") << QString( "") << QHostAddress::Broadcast << false; |
252 | |
253 | QTest::newRow(dataTag: "broadcast_1") << QString( "255.255.255.255") << QHostAddress::Any << false; |
254 | QTest::newRow(dataTag: "broadcast_2") << QString( "255.255.255.255") << QHostAddress::Broadcast << true; |
255 | |
256 | QTest::newRow(dataTag: "any_ipv6") << QString( "::") << QHostAddress::AnyIPv6 << true; |
257 | QTest::newRow(dataTag: "any_ipv4") << QString( "0.0.0.0") << QHostAddress::AnyIPv4 << true; |
258 | |
259 | QTest::newRow(dataTag: "dual_not_ipv6") << QString( "::") << QHostAddress::Any << false; |
260 | QTest::newRow(dataTag: "dual_not_ipv4") << QString( "0.0.0.0") << QHostAddress::Any << false; |
261 | } |
262 | |
263 | |
264 | void tst_QHostAddress::specialAddresses() |
265 | { |
266 | QFETCH(QString, text); |
267 | QFETCH(QHostAddress::SpecialAddress, address); |
268 | QFETCH(bool, result); |
269 | QCOMPARE(QHostAddress(text) == address, result); |
270 | |
271 | //check special address equal to itself (QTBUG-22898), note two overloads of operator== |
272 | QVERIFY(QHostAddress(address) == QHostAddress(address)); |
273 | QVERIFY(QHostAddress(address) == address); |
274 | QVERIFY(address == QHostAddress(address)); |
275 | QVERIFY(!(QHostAddress(address) != QHostAddress(address))); |
276 | QVERIFY(!(QHostAddress(address) != address)); |
277 | QVERIFY(!(address != QHostAddress(address))); |
278 | |
279 | { |
280 | QHostAddress ha; |
281 | ha.setAddress(address); |
282 | QVERIFY(ha == address); |
283 | } |
284 | |
285 | QHostAddress setter; |
286 | setter.setAddress(text); |
287 | QCOMPARE(setter == address, result); |
288 | } |
289 | |
290 | |
291 | void tst_QHostAddress::compare_data() |
292 | { |
293 | QTest::addColumn<QHostAddress>(name: "first"); |
294 | QTest::addColumn<QHostAddress>(name: "second"); |
295 | QTest::addColumn<bool>(name: "result"); |
296 | |
297 | QTest::newRow(dataTag: "1") << QHostAddress() << QHostAddress() << true; |
298 | QTest::newRow(dataTag: "2") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::Any) << true; |
299 | QTest::newRow(dataTag: "3") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6) << true; |
300 | QTest::newRow(dataTag: "4") << QHostAddress(QHostAddress::Broadcast) << QHostAddress(QHostAddress::Broadcast) << true; |
301 | QTest::newRow(dataTag: "5") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::Broadcast) << false; |
302 | QTest::newRow(dataTag: "6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << false; |
303 | QTest::newRow(dataTag: "7") << QHostAddress() << QHostAddress(QHostAddress::LocalHostIPv6) << false; |
304 | QTest::newRow(dataTag: "any4-any6") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::AnyIPv6) << false; |
305 | |
306 | Q_IPV6ADDR localhostv4mapped = { .c: { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 127, 0, 0, 1 } }; |
307 | QTest::newRow(dataTag: "v4-v4mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "::ffff:127.0.0.1") << false; |
308 | QTest::newRow(dataTag: "v4-v4mapped-2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(localhostv4mapped) << false; |
309 | } |
310 | |
311 | void tst_QHostAddress::compare() |
312 | { |
313 | QFETCH(QHostAddress, first); |
314 | QFETCH(QHostAddress, second); |
315 | QFETCH(bool, result); |
316 | |
317 | QCOMPARE(first == second, result); |
318 | QCOMPARE(second == first, result); |
319 | if (result == true) |
320 | QCOMPARE(qHash(first), qHash(second)); |
321 | } |
322 | |
323 | void tst_QHostAddress::isEqual_data() |
324 | { |
325 | QTest::addColumn<QHostAddress>(name: "first"); |
326 | QTest::addColumn<QHostAddress>(name: "second"); |
327 | QTest::addColumn<int>(name: "flags"); |
328 | QTest::addColumn<bool>(name: "result"); |
329 | |
330 | // QHostAddress::StrictConversion is already tested in compare() |
331 | QTest::newRow(dataTag: "localhost4to6-local") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertLocalHost << true; |
332 | QTest::newRow(dataTag: "localhost4to6-compat") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4CompatToIPv4 << false; |
333 | QTest::newRow(dataTag: "localhost4to6-mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4MappedToIPv4 << false; |
334 | QTest::newRow(dataTag: "localhost4to6-unspec") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << false; |
335 | QTest::newRow(dataTag: "0.0.0.1-::1-local") << QHostAddress( "0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertLocalHost << false; |
336 | QTest::newRow(dataTag: "v4-v4compat-local") << QHostAddress( "192.168.1.1") << QHostAddress( "::192.168.1.1") << (int)QHostAddress::ConvertLocalHost << false; |
337 | QTest::newRow(dataTag: "v4-v4mapped-local") << QHostAddress( "192.168.1.1") << QHostAddress( "::ffff:192.168.1.1") << (int)QHostAddress::ConvertLocalHost << false; |
338 | QTest::newRow(dataTag: "0.0.0.1-::1-unspec") << QHostAddress( "0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << false; |
339 | QTest::newRow(dataTag: "v4-v4compat-unspec") << QHostAddress( "192.168.1.1") << QHostAddress( "::192.168.1.1") << (int)QHostAddress::ConvertUnspecifiedAddress << false; |
340 | QTest::newRow(dataTag: "v4-v4mapped-unspec") << QHostAddress( "192.168.1.1") << QHostAddress( "::ffff:192.168.1.1") << (int)QHostAddress::ConvertUnspecifiedAddress << false; |
341 | QTest::newRow(dataTag: "0.0.0.1-::1-compat") << QHostAddress( "0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4CompatToIPv4 << false; |
342 | QTest::newRow(dataTag: "v4-v4compat-compat") << QHostAddress( "192.168.1.1") << QHostAddress( "::192.168.1.1") << (int)QHostAddress::ConvertV4CompatToIPv4 << true; |
343 | QTest::newRow(dataTag: "v4-v4mapped-compat") << QHostAddress( "192.168.1.1") << QHostAddress( "::ffff:192.168.1.1") << (int)QHostAddress::ConvertV4CompatToIPv4 << false; |
344 | QTest::newRow(dataTag: "0.0.0.1-::1-mapped") << QHostAddress( "0.0.0.1") << QHostAddress(QHostAddress::LocalHostIPv6) << (int)QHostAddress::ConvertV4MappedToIPv4 << false; |
345 | QTest::newRow(dataTag: "v4-v4compat-mapped") << QHostAddress( "192.168.1.1") << QHostAddress( "::192.168.1.1") << (int)QHostAddress::ConvertV4MappedToIPv4 << false; |
346 | QTest::newRow(dataTag: "v4-v4mapped-mapped") << QHostAddress( "192.168.1.1") << QHostAddress( "::FFFF:192.168.1.1") << (int)QHostAddress::ConvertV4MappedToIPv4 << true; |
347 | QTest::newRow(dataTag: "undef-any-local") << QHostAddress() << QHostAddress(QHostAddress::Any) << (int)QHostAddress::ConvertLocalHost << false; |
348 | QTest::newRow(dataTag: "undef-any-unspec") << QHostAddress() << QHostAddress(QHostAddress::Any) << (int)QHostAddress::ConvertUnspecifiedAddress << false; |
349 | QTest::newRow(dataTag: "anyv6-anyv4-compat") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertV4CompatToIPv4 << true; |
350 | QTest::newRow(dataTag: "anyv6-anyv4-mapped") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertV4MappedToIPv4 << false; |
351 | QTest::newRow(dataTag: "anyv6-anyv4-unspec") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertUnspecifiedAddress << true; |
352 | QTest::newRow(dataTag: "any-anyv4-unspec") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertUnspecifiedAddress << true; |
353 | QTest::newRow(dataTag: "any-anyv6-unspec") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::ConvertUnspecifiedAddress << true; |
354 | QTest::newRow(dataTag: "anyv6-anyv4-local") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false; |
355 | QTest::newRow(dataTag: "any-anyv4-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv4) << (int)QHostAddress::ConvertLocalHost << false; |
356 | QTest::newRow(dataTag: "any-anyv6-local") << QHostAddress(QHostAddress::Any) << QHostAddress(QHostAddress::AnyIPv6) << (int)QHostAddress::ConvertLocalHost << false; |
357 | } |
358 | |
359 | void tst_QHostAddress::isEqual() |
360 | { |
361 | QFETCH(QHostAddress, first); |
362 | QFETCH(QHostAddress, second); |
363 | QFETCH(int, flags); |
364 | QFETCH(bool, result); |
365 | |
366 | QCOMPARE(first.isEqual(second, QHostAddress::ConversionModeFlag(flags)), result); |
367 | QCOMPARE(second.isEqual(first, QHostAddress::ConversionModeFlag(flags)), result); |
368 | } |
369 | |
370 | QT_WARNING_PUSH |
371 | #ifdef QT_WARNING_DISABLE_DEPRECATED |
372 | QT_WARNING_DISABLE_DEPRECATED |
373 | #endif |
374 | |
375 | void tst_QHostAddress::assignment() |
376 | { |
377 | QHostAddress address; |
378 | |
379 | #if QT_DEPRECATED_SINCE(5, 8) |
380 | address = "127.0.0.1"; |
381 | QCOMPARE(address, QHostAddress("127.0.0.1")); |
382 | |
383 | address = "::1"; |
384 | QCOMPARE(address, QHostAddress("::1")); |
385 | #endif |
386 | |
387 | // WinRT does not support sockaddr_in |
388 | #ifndef Q_OS_WINRT |
389 | QHostAddress addr("4.2.2.1"); |
390 | sockaddr_in sockAddr; |
391 | sockAddr.sin_family = AF_INET; |
392 | sockAddr.sin_addr.s_addr = htonl(hostlong: addr.toIPv4Address()); |
393 | address.setAddress((sockaddr *)&sockAddr); |
394 | QCOMPARE(address, addr); |
395 | #endif // !Q_OS_WINRT |
396 | } |
397 | |
398 | QT_WARNING_POP |
399 | |
400 | void tst_QHostAddress::scopeId() |
401 | { |
402 | QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0"); |
403 | QCOMPARE(address.scopeId(), QString("eth0")); |
404 | QCOMPARE(address.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); |
405 | |
406 | QHostAddress address2("fe80::2e0:4cff:fefb:662a"); |
407 | QCOMPARE(address2.scopeId(), QString()); |
408 | address2.setScopeId(QString("en0")); |
409 | QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%en0")); |
410 | |
411 | address2 = address; |
412 | QCOMPARE(address2.scopeId(), QString("eth0")); |
413 | QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); |
414 | } |
415 | |
416 | void tst_QHostAddress::hashKey() |
417 | { |
418 | QHash<QHostAddress, QString> hostHash; |
419 | hostHash.insert(akey: QHostAddress(), avalue: "ole"); |
420 | } |
421 | |
422 | void tst_QHostAddress::streaming_data() |
423 | { |
424 | QTest::addColumn<QHostAddress>(name: "address"); |
425 | QTest::newRow(dataTag: "1") << QHostAddress(); |
426 | QTest::newRow(dataTag: "2") << QHostAddress(0xDEADBEEF); |
427 | QTest::newRow(dataTag: "3") << QHostAddress( "127.128.129.130"); |
428 | QTest::newRow(dataTag: "4") << QHostAddress( "1080:0000:0000:0000:0008:0800:200C:417A"); |
429 | QTest::newRow(dataTag: "5") << QHostAddress( "fe80::2e0:4cff:fefb:662a%eth0"); |
430 | QTest::newRow(dataTag: "6") << QHostAddress(QHostAddress::Null); |
431 | QTest::newRow(dataTag: "7") << QHostAddress(QHostAddress::LocalHost); |
432 | QTest::newRow(dataTag: "8") << QHostAddress(QHostAddress::LocalHostIPv6); |
433 | QTest::newRow(dataTag: "9") << QHostAddress(QHostAddress::Broadcast); |
434 | QTest::newRow(dataTag: "10") << QHostAddress(QHostAddress::Any); |
435 | QTest::newRow(dataTag: "11") << QHostAddress(QHostAddress::AnyIPv4); |
436 | QTest::newRow(dataTag: "12") << QHostAddress(QHostAddress::AnyIPv6); |
437 | QTest::newRow(dataTag: "13") << QHostAddress( "foo.bar.com"); |
438 | } |
439 | |
440 | void tst_QHostAddress::streaming() |
441 | { |
442 | QFETCH(QHostAddress, address); |
443 | QByteArray ba; |
444 | QDataStream ds1(&ba, QIODevice::WriteOnly); |
445 | ds1 << address; |
446 | QCOMPARE(ds1.status(), QDataStream::Ok); |
447 | QDataStream ds2(&ba, QIODevice::ReadOnly); |
448 | QHostAddress address2; |
449 | ds2 >> address2; |
450 | QCOMPARE(ds2.status(), QDataStream::Ok); |
451 | QCOMPARE(address, address2); |
452 | } |
453 | |
454 | void tst_QHostAddress::parseSubnet_data() |
455 | { |
456 | QTest::addColumn<QString>(name: "subnet"); |
457 | QTest::addColumn<QHostAddress>(name: "prefix"); |
458 | QTest::addColumn<int>(name: "prefixLength"); |
459 | |
460 | // invalid/error values |
461 | QTest::newRow(dataTag: "empty") << QString() << QHostAddress() << -1; |
462 | QTest::newRow(dataTag: "invalid_01") << "foobar"<< QHostAddress() << -1; |
463 | QTest::newRow(dataTag: "invalid_02") << " "<< QHostAddress() << -1; |
464 | QTest::newRow(dataTag: "invalid_03") << "1.2.3.a"<< QHostAddress() << -1; |
465 | QTest::newRow(dataTag: "invalid_04") << "1.2.3.4.5"<< QHostAddress() << -1; |
466 | QTest::newRow(dataTag: "invalid_05") << "1.2.3.4:80"<< QHostAddress() << -1; |
467 | QTest::newRow(dataTag: "invalid_06") << "1.2.3.4/33"<< QHostAddress() << -1; |
468 | QTest::newRow(dataTag: "invalid_07") << "1.2.3.4/-1"<< QHostAddress() << -1; |
469 | QTest::newRow(dataTag: "invalid_08") << "1.2.3.4/256.0.0.0"<< QHostAddress() << -1; |
470 | QTest::newRow(dataTag: "invalid_09") << "1.2.3.4/255.253.0.0"<< QHostAddress() << -1; |
471 | QTest::newRow(dataTag: "invalid_10") << "1.2.3.4/255.0.0.255"<< QHostAddress() << -1; |
472 | QTest::newRow(dataTag: "invalid_11") << "1.2.3.4."<< QHostAddress() << -1; |
473 | QTest::newRow(dataTag: "invalid_20") << "ffff::/-1"<< QHostAddress() << -1; |
474 | QTest::newRow(dataTag: "invalid_21") << "ffff::/129"<< QHostAddress() << -1; |
475 | QTest::newRow(dataTag: "invalid_22") << "ffff::/255.255.0.0"<< QHostAddress() << -1; |
476 | QTest::newRow(dataTag: "invalid_23") << "ffff::/ff00::"<< QHostAddress() << -1; |
477 | |
478 | // correct IPv4 with netmask |
479 | QTest::newRow(dataTag: "netmask_0") << "0.0.0.0/0.0.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 0; |
480 | QTest::newRow(dataTag: "netmask_1") << "0.0.0.0/255.128.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 9; |
481 | QTest::newRow(dataTag: "netmask_2") << "0.0.0.0/255.192.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 10; |
482 | QTest::newRow(dataTag: "netmask_3") << "0.0.0.0/255.224.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 11; |
483 | QTest::newRow(dataTag: "netmask_4") << "0.0.0.0/255.240.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 12; |
484 | QTest::newRow(dataTag: "netmask_5") << "0.0.0.0/255.248.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 13; |
485 | QTest::newRow(dataTag: "netmask_6") << "0.0.0.0/255.252.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 14; |
486 | QTest::newRow(dataTag: "netmask_7") << "0.0.0.0/255.254.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 15; |
487 | QTest::newRow(dataTag: "netmask_8") << "0.0.0.0/255.255.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 16; |
488 | QTest::newRow(dataTag: "netmask_16") << "0.0.0.0/255.255.0.0"<< QHostAddress(QHostAddress::AnyIPv4) << 16; |
489 | QTest::newRow(dataTag: "netmask_24") << "0.0.0.0/255.255.255.0"<< QHostAddress(QHostAddress::AnyIPv4) << 24; |
490 | QTest::newRow(dataTag: "netmask_31") << "0.0.0.0/255.255.255.254"<< QHostAddress(QHostAddress::AnyIPv4) << 31; |
491 | QTest::newRow(dataTag: "netmask_32") << "0.0.0.0/255.255.255.255"<< QHostAddress(QHostAddress::AnyIPv4) << 32; |
492 | |
493 | // correct IPv4 with prefix |
494 | QTest::newRow(dataTag: "prefix_0") << "0.0.0.0/0"<< QHostAddress(QHostAddress::AnyIPv4) << 0; |
495 | QTest::newRow(dataTag: "prefix_1") << "0.0.0.0/1"<< QHostAddress(QHostAddress::AnyIPv4) << 1; |
496 | QTest::newRow(dataTag: "prefix_9") << "0.0.0.0/9"<< QHostAddress(QHostAddress::AnyIPv4) << 9; |
497 | QTest::newRow(dataTag: "prefix_31") << "0.0.0.0/31"<< QHostAddress(QHostAddress::AnyIPv4) << 31; |
498 | QTest::newRow(dataTag: "prefix_32") << "0.0.0.0/32"<< QHostAddress(QHostAddress::AnyIPv4) << 32; |
499 | |
500 | // correct IPv4 without prefix or netmask |
501 | QTest::newRow(dataTag: "classA") << "10"<< QHostAddress( "10.0.0.0") << 8; |
502 | QTest::newRow(dataTag: "classA+dot") << "10."<< QHostAddress( "10.0.0.0") << 8; |
503 | QTest::newRow(dataTag: "classB") << "172.16"<< QHostAddress( "172.16.0.0") << 16; |
504 | QTest::newRow(dataTag: "classB+dot") << "172.16."<< QHostAddress( "172.16.0.0") << 16; |
505 | QTest::newRow(dataTag: "classC") << "192.168.0"<< QHostAddress( "192.168.0.0") << 24; |
506 | QTest::newRow(dataTag: "classC+dot") << "192.168.0"<< QHostAddress( "192.168.0.0") << 24; |
507 | QTest::newRow(dataTag: "full-ipv4") << "192.168.0.1"<< QHostAddress( "192.168.0.1") << 32; |
508 | |
509 | // correct IPv6 with prefix |
510 | QTest::newRow(dataTag: "ipv6_01") << "::/0"<< QHostAddress(QHostAddress::AnyIPv6) << 0; |
511 | QTest::newRow(dataTag: "ipv6_03") << "::/3"<< QHostAddress(QHostAddress::AnyIPv6) << 3; |
512 | QTest::newRow(dataTag: "ipv6_16") << "::/16"<< QHostAddress(QHostAddress::AnyIPv6) << 16; |
513 | QTest::newRow(dataTag: "ipv6_48") << "::/48"<< QHostAddress(QHostAddress::AnyIPv6) << 48; |
514 | QTest::newRow(dataTag: "ipv6_127") << "::/127"<< QHostAddress(QHostAddress::AnyIPv6) << 127; |
515 | QTest::newRow(dataTag: "ipv6_128") << "::/128"<< QHostAddress(QHostAddress::AnyIPv6) << 128; |
516 | |
517 | // tail bit clearing: |
518 | QTest::newRow(dataTag: "clear_01") << "255.255.255.255/31"<< QHostAddress( "255.255.255.254") << 31; |
519 | QTest::newRow(dataTag: "clear_08") << "255.255.255.255/24"<< QHostAddress( "255.255.255.0") << 24; |
520 | QTest::newRow(dataTag: "clear_09") << "255.255.255.255/23"<< QHostAddress( "255.255.254.0") << 23; |
521 | QTest::newRow(dataTag: "clear_10") << "255.255.255.255/22"<< QHostAddress( "255.255.252.0") << 22; |
522 | QTest::newRow(dataTag: "clear_11") << "255.255.255.255/21"<< QHostAddress( "255.255.248.0") << 21; |
523 | QTest::newRow(dataTag: "clear_12") << "255.255.255.255/20"<< QHostAddress( "255.255.240.0") << 20; |
524 | QTest::newRow(dataTag: "clear_13") << "255.255.255.255/19"<< QHostAddress( "255.255.224.0") << 19; |
525 | QTest::newRow(dataTag: "clear_14") << "255.255.255.255/18"<< QHostAddress( "255.255.192.0") << 18; |
526 | QTest::newRow(dataTag: "clear_15") << "255.255.255.255/17"<< QHostAddress( "255.255.128.0") << 17; |
527 | QTest::newRow(dataTag: "clear_16") << "255.255.255.255/16"<< QHostAddress( "255.255.0.0") << 16; |
528 | QTest::newRow(dataTag: "clear_24") << "255.255.255.255/8"<< QHostAddress( "255.0.0.0") << 8; |
529 | QTest::newRow(dataTag: "clear_31") << "255.255.255.255/1"<< QHostAddress( "128.0.0.0") << 1; |
530 | QTest::newRow(dataTag: "clear_32") << "255.255.255.255/0"<< QHostAddress( "0.0.0.0") << 0; |
531 | |
532 | // same for IPv6: |
533 | QTest::newRow(dataTag: "ipv6_clear_01") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/127" |
534 | << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe") |
535 | << 127; |
536 | QTest::newRow(dataTag: "ipv6_clear_07") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/121" |
537 | << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80") |
538 | << 121; |
539 | QTest::newRow(dataTag: "ipv6_clear_08") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/120" |
540 | << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00") |
541 | << 120; |
542 | QTest::newRow(dataTag: "ipv6_clear_16") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/112" |
543 | << QHostAddress("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0") |
544 | << 112; |
545 | QTest::newRow(dataTag: "ipv6_clear_80") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/48" |
546 | << QHostAddress("ffff:ffff:ffff::") |
547 | << 48; |
548 | QTest::newRow(dataTag: "ipv6_clear_81") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/47" |
549 | << QHostAddress("ffff:ffff:fffe::") |
550 | << 47; |
551 | QTest::newRow(dataTag: "ipv6_clear_82") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/46" |
552 | << QHostAddress("ffff:ffff:fffc::") |
553 | << 46; |
554 | QTest::newRow(dataTag: "ipv6_clear_83") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/45" |
555 | << QHostAddress("ffff:ffff:fff8::") |
556 | << 45; |
557 | QTest::newRow(dataTag: "ipv6_clear_84") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/44" |
558 | << QHostAddress("ffff:ffff:fff0::") |
559 | << 44; |
560 | QTest::newRow(dataTag: "ipv6_clear_85") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/43" |
561 | << QHostAddress("ffff:ffff:ffe0::") |
562 | << 43; |
563 | QTest::newRow(dataTag: "ipv6_clear_86") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/42" |
564 | << QHostAddress("ffff:ffff:ffc0::") |
565 | << 42; |
566 | QTest::newRow(dataTag: "ipv6_clear_87") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/41" |
567 | << QHostAddress("ffff:ffff:ff80::") |
568 | << 41; |
569 | QTest::newRow(dataTag: "ipv6_clear_88") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/40" |
570 | << QHostAddress("ffff:ffff:ff00::") |
571 | << 40; |
572 | QTest::newRow(dataTag: "ipv6_clear_125") << "3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/3" |
573 | << QHostAddress("2000::") |
574 | << 3; |
575 | QTest::newRow(dataTag: "ipv6_clear_127") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/1" |
576 | << QHostAddress("8000::") |
577 | << 1; |
578 | QTest::newRow(dataTag: "ipv6_clear_128") << "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0" |
579 | << QHostAddress(QHostAddress::AnyIPv6) |
580 | << 0; |
581 | } |
582 | |
583 | void tst_QHostAddress::parseSubnet() |
584 | { |
585 | QFETCH(QString, subnet); |
586 | QFETCH(QHostAddress, prefix); |
587 | QFETCH(int, prefixLength); |
588 | |
589 | QPair<QHostAddress, int> result = QHostAddress::parseSubnet(subnet); |
590 | QCOMPARE(result.first, prefix); |
591 | QCOMPARE(result.second, prefixLength); |
592 | } |
593 | |
594 | void tst_QHostAddress::isInSubnet_data() |
595 | { |
596 | QTest::addColumn<QHostAddress>(name: "address"); |
597 | QTest::addColumn<QHostAddress>(name: "prefix"); |
598 | QTest::addColumn<int>(name: "prefixLength"); |
599 | QTest::addColumn<bool>(name: "result"); |
600 | |
601 | // invalid QHostAddresses are never in any subnets |
602 | QTest::newRow(dataTag: "invalid_01") << QHostAddress() << QHostAddress() << 32 << false; |
603 | QTest::newRow(dataTag: "invalid_02") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 32 << false; |
604 | QTest::newRow(dataTag: "invalid_03") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 8 << false; |
605 | QTest::newRow(dataTag: "invalid_04") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv4) << 0 << false; |
606 | QTest::newRow(dataTag: "invalid_05") << QHostAddress() << QHostAddress( "255.255.255.0") << 24 << false; |
607 | QTest::newRow(dataTag: "invalid_06") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 0 << false; |
608 | QTest::newRow(dataTag: "invalid_07") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 32 << false; |
609 | QTest::newRow(dataTag: "invalid_08") << QHostAddress() << QHostAddress(QHostAddress::AnyIPv6) << 128<< false; |
610 | |
611 | // and no host address can be in a subnet whose prefix is invalid |
612 | QTest::newRow(dataTag: "invalid_20") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress() << 16 << false; |
613 | QTest::newRow(dataTag: "invalid_21") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress() << 16 << false; |
614 | QTest::newRow(dataTag: "invalid_22") << QHostAddress(QHostAddress::LocalHost) << QHostAddress() << 16 << false; |
615 | QTest::newRow(dataTag: "invalid_23") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress() << 16 << false; |
616 | |
617 | // negative netmasks don't make sense: |
618 | QTest::newRow(dataTag: "invalid_30") << QHostAddress(QHostAddress::AnyIPv4) << QHostAddress(QHostAddress::Any) << -1 << false; |
619 | QTest::newRow(dataTag: "invalid_31") << QHostAddress(QHostAddress::AnyIPv6) << QHostAddress(QHostAddress::AnyIPv6) << -1 << false; |
620 | |
621 | // we don't support IPv4 belonging in an IPv6 netmask and vice-versa |
622 | QTest::newRow(dataTag: "v4-in-v6") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv6) << 0 << false; |
623 | QTest::newRow(dataTag: "v6-in-v4") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::Any) << 0 << false; |
624 | QTest::newRow(dataTag: "v4-in-v6mapped") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "ffff:ffff:ffff:ffff:ffff:ffff:255.0.0.0") << 113 << false; |
625 | QTest::newRow(dataTag: "v4-in-v6mapped2") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "::ffff:255.0.0.0") << 113 << false; |
626 | |
627 | // IPv4 correct ones |
628 | QTest::newRow(dataTag: "netmask_0") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << 0 << true; |
629 | QTest::newRow(dataTag: "netmask_0bis") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "255.255.0.0") << 0 << true; |
630 | QTest::newRow(dataTag: "netmask_0ter") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "1.2.3.4") << 0 << true; |
631 | QTest::newRow(dataTag: "netmask_1") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::AnyIPv4) << 1 << true; |
632 | QTest::newRow(dataTag: "~netmask_1") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "128.0.0.0") << 1 << false; |
633 | QTest::newRow(dataTag: "netmask_1bis") << QHostAddress( "224.0.0.1") << QHostAddress( "128.0.0.0") << 1 << true; |
634 | QTest::newRow(dataTag: "~netmask_1bis") << QHostAddress( "224.0.0.1") << QHostAddress( "0.0.0.0") << 1 << false; |
635 | QTest::newRow(dataTag: "netmask_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "127.0.0.0") << 8 << true; |
636 | QTest::newRow(dataTag: "~netmask_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress( "126.0.0.0") << 8 << false; |
637 | QTest::newRow(dataTag: "netmask_15") << QHostAddress( "10.0.1.255") << QHostAddress( "10.0.0.0") << 15 << true; |
638 | QTest::newRow(dataTag: "netmask_16") << QHostAddress( "172.16.0.1") << QHostAddress( "172.16.0.0") << 16 << true; |
639 | |
640 | // the address is always in the subnet containing its address, regardless of length: |
641 | QTest::newRow(dataTag: "same_01") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 1 << true; |
642 | QTest::newRow(dataTag: "same_07") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 7 << true; |
643 | QTest::newRow(dataTag: "same_8") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 8 << true; |
644 | QTest::newRow(dataTag: "same_24") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 23 << true; |
645 | QTest::newRow(dataTag: "same_31") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 31 << true; |
646 | QTest::newRow(dataTag: "same_32") << QHostAddress(QHostAddress::LocalHost) << QHostAddress(QHostAddress::LocalHost) << 32 << true; |
647 | |
648 | // IPv6 correct ones: |
649 | QTest::newRow(dataTag: "ipv6_netmask_0") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << 0 << true; |
650 | QTest::newRow(dataTag: "ipv6_netmask_0bis") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::LocalHostIPv6) << 0 << true; |
651 | QTest::newRow(dataTag: "ipv6_netmask_0ter") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress( "ffff::") << 0 << true; |
652 | QTest::newRow(dataTag: "ipv6_netmask_1") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress(QHostAddress::AnyIPv6) << 1 << true; |
653 | QTest::newRow(dataTag: "ipv6_netmask_1bis") << QHostAddress( "fec0::1") << QHostAddress( "8000::") << 1 << true; |
654 | QTest::newRow(dataTag: "~ipv6_netmask_1") << QHostAddress(QHostAddress::LocalHostIPv6) << QHostAddress( "8000::") << 1 << false; |
655 | QTest::newRow(dataTag: "~ipv6_netmask_1bis") << QHostAddress( "fec0::1") << QHostAddress( "::") << 1 << false; |
656 | QTest::newRow(dataTag: "ipv6_netmask_47") << QHostAddress( "2:3:5::1") << QHostAddress( "2:3:4::") << 47 << true; |
657 | QTest::newRow(dataTag: "ipv6_netmask_48") << QHostAddress( "2:3:4::1") << QHostAddress( "2:3:4::") << 48 << true; |
658 | QTest::newRow(dataTag: "~ipv6_netmask_48") << QHostAddress( "2:3:5::1") << QHostAddress( "2:3:4::") << 48 << false; |
659 | QTest::newRow(dataTag: "ipv6_netmask_127") << QHostAddress( "2:3:4:5::1") << QHostAddress( "2:3:4:5::") << 127 << true; |
660 | QTest::newRow(dataTag: "ipv6_netmask_128") << QHostAddress( "2:3:4:5::1") << QHostAddress( "2:3:4:5::1") << 128 << true; |
661 | QTest::newRow(dataTag: "~ipv6_netmask_128") << QHostAddress( "2:3:4:5::1") << QHostAddress( "2:3:4:5::0") << 128 << false; |
662 | } |
663 | |
664 | void tst_QHostAddress::isInSubnet() |
665 | { |
666 | QFETCH(QHostAddress, address); |
667 | QFETCH(QHostAddress, prefix); |
668 | QFETCH(int, prefixLength); |
669 | |
670 | QTEST(address.isInSubnet(prefix, prefixLength), "result"); |
671 | } |
672 | |
673 | void tst_QHostAddress::classification_data() |
674 | { |
675 | QTest::addColumn<QHostAddress>(name: "address"); |
676 | QTest::addColumn<AddressClassification>(name: "result"); |
677 | |
678 | QTest::newRow(dataTag: "default") << QHostAddress() << UnknownAddress; |
679 | QTest::newRow(dataTag: "invalid") << QHostAddress( "&&&") << UnknownAddress; |
680 | |
681 | QTest::newRow(dataTag: "Any") << QHostAddress(QHostAddress::Any) << LocalNetAddress; |
682 | QTest::newRow(dataTag: "Null") << QHostAddress(QHostAddress::Null) << UnknownAddress; |
683 | |
684 | // IPv6 address space |
685 | auto addV6 = [](const char *str, AddressClassification cl) { |
686 | QTest::newRow(dataTag: str) << QHostAddress(str) << cl; |
687 | }; |
688 | QTest::newRow(dataTag: "AnyIPv6") << QHostAddress(QHostAddress::AnyIPv6) << LocalNetAddress; |
689 | QTest::newRow(dataTag: "ipv6_loop") << QHostAddress(QHostAddress::LocalHostIPv6) << LoopbackAddress; |
690 | addV6("::", LocalNetAddress); |
691 | addV6("::1", LoopbackAddress); |
692 | addV6("::2", GlobalAddress); |
693 | addV6("2000::", GlobalAddress); |
694 | addV6("3fff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress); |
695 | addV6("fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", GlobalAddress); |
696 | addV6("fc00::", UniqueLocalAddress); |
697 | addV6("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UniqueLocalAddress); |
698 | addV6("fe00::", UnknownAddress); |
699 | addV6("fe7f:ffff:ffff:ffff:ffff:ffff:ffff:ffff", UnknownAddress); |
700 | addV6("fe80::", LinkLocalAddress); |
701 | addV6("febf:ffff:ffff:ffff:ffff:ffff:ffff:ffff", LinkLocalAddress); |
702 | addV6("fec0::", SiteLocalAddress); |
703 | addV6("feff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", SiteLocalAddress); |
704 | addV6("ff00::", MulticastAddress); |
705 | addV6("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", MulticastAddress); |
706 | |
707 | // IPv4 address space |
708 | auto addV4 = [](const char *str, AddressClassification cl) { |
709 | QTest::newRow(dataTag: str) << QHostAddress(str) << cl; |
710 | QByteArray v6 = "::ffff:"; |
711 | v6 += str; |
712 | QTest::newRow(dataTag: v6.constData()) << QHostAddress(QString::fromLatin1(str: v6)) << cl; |
713 | }; |
714 | QTest::newRow(dataTag: "AnyIPv4") << QHostAddress(QHostAddress::AnyIPv4) << LocalNetAddress; |
715 | QTest::newRow(dataTag: "ipv4_loop") << QHostAddress(QHostAddress::LocalHost) << LoopbackAddress; |
716 | QTest::newRow(dataTag: "Broadcast") << QHostAddress(QHostAddress::Broadcast) << BroadcastAddress; |
717 | addV4("0.0.0.0", LocalNetAddress); |
718 | addV4("0.0.0.1", LocalNetAddress); |
719 | addV4("0.255.255.255", LocalNetAddress); |
720 | addV4("1.0.0.0", GlobalAddress); |
721 | addV4("1.2.3.4", GlobalAddress); |
722 | addV4("10.0.0.4", PrivateNetworkAddress); |
723 | addV4("127.0.0.1", LoopbackAddress); |
724 | addV4("127.0.0.2", LoopbackAddress); |
725 | addV4("127.255.255.255", LoopbackAddress); |
726 | addV4("192.168.3.4", PrivateNetworkAddress); |
727 | addV4("223.255.255.255", GlobalAddress); |
728 | addV4("224.0.0.0", MulticastAddress); |
729 | addV4("239.255.255.255", MulticastAddress); |
730 | addV4("240.0.0.0", UnknownAddress); |
731 | addV4("255.255.255.254", UnknownAddress); |
732 | addV4("255.255.255.255", BroadcastAddress); |
733 | } |
734 | |
735 | void tst_QHostAddress::classification() |
736 | { |
737 | QFETCH(QHostAddress, address); |
738 | QFETCH(AddressClassification, result); |
739 | |
740 | bool isLoopback = (result == LoopbackAddress); |
741 | bool isGlobal = (result & GlobalAddress); // GlobalAddress is a bit |
742 | bool isLinkLocal = (result == LinkLocalAddress); |
743 | bool isSiteLocal = (result == SiteLocalAddress); |
744 | bool isUniqueLocalAddress = (result == UniqueLocalAddress); |
745 | bool isMulticast = (result == MulticastAddress); |
746 | bool isBroadcast = (result == BroadcastAddress); |
747 | |
748 | QCOMPARE(address.isLoopback(), isLoopback); |
749 | QCOMPARE(address.isGlobal(), isGlobal); |
750 | QCOMPARE(address.isLinkLocal(), isLinkLocal); |
751 | QCOMPARE(address.isSiteLocal(), isSiteLocal); |
752 | QCOMPARE(address.isUniqueLocalUnicast(), isUniqueLocalAddress); |
753 | QCOMPARE(address.isMulticast(), isMulticast); |
754 | QCOMPARE(address.isBroadcast(), isBroadcast); |
755 | } |
756 | |
757 | void tst_QHostAddress::convertv4v6_data() |
758 | { |
759 | QTest::addColumn<QHostAddress>(name: "source"); |
760 | QTest::addColumn<int>(name: "protocol"); |
761 | QTest::addColumn<QHostAddress>(name: "result"); |
762 | |
763 | QTest::newRow(dataTag: "any-to-v4") << QHostAddress(QHostAddress::Any) << 4 << QHostAddress(QHostAddress::AnyIPv4); |
764 | QTest::newRow(dataTag: "any-to-v6") << QHostAddress(QHostAddress::Any) << 6 << QHostAddress(QHostAddress::AnyIPv6); |
765 | QTest::newRow(dataTag: "anyv4-to-v6") << QHostAddress(QHostAddress::AnyIPv4) << 6 << QHostAddress(QHostAddress::AnyIPv6); |
766 | QTest::newRow(dataTag: "anyv6-to-v4") << QHostAddress(QHostAddress::AnyIPv6) << 4 << QHostAddress(QHostAddress::AnyIPv4); |
767 | |
768 | QTest::newRow(dataTag: "v4mapped-to-v4") << QHostAddress( "::ffff:192.0.2.1") << 4 << QHostAddress( "192.0.2.1"); |
769 | QTest::newRow(dataTag: "v4-to-v4mapped") << QHostAddress( "192.0.2.1") << 6 << QHostAddress( "::ffff:192.0.2.1"); |
770 | |
771 | // we won't convert 127.0.0.1 to ::1 or vice-versa: |
772 | // you can connect to a v4 server socket with ::ffff:127.0.0.1, but not with ::1 |
773 | QTest::newRow(dataTag: "localhost-to-v4mapped") << QHostAddress(QHostAddress::LocalHost) << 6 << QHostAddress( "::ffff:127.0.0.1"); |
774 | QTest::newRow(dataTag: "v4mapped-to-localhost") << QHostAddress( "::ffff:127.0.0.1") << 4 << QHostAddress(QHostAddress::LocalHost); |
775 | |
776 | // in turn, that means localhost6 doesn't convert to v4 |
777 | QTest::newRow(dataTag: "localhost6-to-v4") << QHostAddress(QHostAddress::LocalHostIPv6) << 4 << QHostAddress(); |
778 | |
779 | // some other v6 addresses that won't convert to v4 |
780 | QTest::newRow(dataTag: "v4compat-to-v4") << QHostAddress( "::192.0.2.1") << 4 << QHostAddress(); |
781 | QTest::newRow(dataTag: "localhostv4compat-to-v4") << QHostAddress( "::127.0.0.1") << 4 << QHostAddress(); |
782 | QTest::newRow(dataTag: "v6global-to-v4") << QHostAddress( "2001:db8::1") << 4 << QHostAddress(); |
783 | QTest::newRow(dataTag: "v6multicast-to-v4") << QHostAddress( "ff02::1") << 4 << QHostAddress(); |
784 | } |
785 | |
786 | void tst_QHostAddress::convertv4v6() |
787 | { |
788 | QFETCH(QHostAddress, source); |
789 | QFETCH(int, protocol); |
790 | QFETCH(QHostAddress, result); |
791 | |
792 | if (protocol == 4) { |
793 | bool ok; |
794 | quint32 v4 = source.toIPv4Address(ok: &ok); |
795 | QCOMPARE(ok, result.protocol() == QAbstractSocket::IPv4Protocol); |
796 | if (ok) |
797 | QCOMPARE(QHostAddress(v4), result); |
798 | } else if (protocol == 6) { |
799 | QCOMPARE(QHostAddress(source.toIPv6Address()), result); |
800 | } |
801 | } |
802 | |
803 | QTEST_MAIN(tst_QHostAddress) |
804 | #include "tst_qhostaddress.moc" |
805 |
Definitions
- tst_QHostAddress
- tst_QHostAddress
- constructor_QString_data
- constructor_QString
- setAddress_QString_data
- setAddress_QString
- specialAddresses_data
- specialAddresses
- compare_data
- compare
- isEqual_data
- isEqual
- assignment
- scopeId
- hashKey
- streaming_data
- streaming
- parseSubnet_data
- parseSubnet
- isInSubnet_data
- isInSubnet
- classification_data
- classification
- convertv4v6_data
Learn Advanced QML with KDAB
Find out more