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 | |