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