Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/tests/core/io/test_ip_address.h
21337 views
1
/**************************************************************************/
2
/* test_ip_address.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/io/ip_address.h"
34
35
#include "tests/test_macros.h"
36
37
namespace TestIPAddress {
38
39
struct IPTester : public IPAddress {
40
public:
41
static bool _test_v4(const char *p_ip) {
42
uint8_t ip[4];
43
return _parse_ipv4(String::utf8(p_ip), 0, ip);
44
}
45
46
static bool _test_v6(const char *p_ip) {
47
IPAddress addr;
48
return _parse_ipv6(String::utf8(p_ip), addr);
49
}
50
51
static bool test_v4(const char *p_ip, bool p_valid) {
52
bool is_6 = _test_v6(p_ip);
53
bool is_4 = _test_v4(p_ip);
54
bool is_valid = IPAddress::is_valid_ip_address(String::utf8(p_ip));
55
IPAddress ip(p_ip);
56
return is_4 == p_valid && is_6 == false && is_valid == p_valid && ip.is_valid() == p_valid && ip.is_wildcard() == false;
57
}
58
59
static bool test_v6(const char *p_ip, bool p_valid) {
60
bool is_6 = _test_v6(p_ip);
61
bool is_4 = _test_v4(p_ip);
62
bool is_valid = is_valid_ip_address(String::utf8(p_ip));
63
IPAddress ip(p_ip);
64
return is_4 == false && is_6 == p_valid && is_valid == p_valid && ip.is_valid() == p_valid && ip.is_wildcard() == false;
65
}
66
67
static bool test_wildcard(const char *p_ip) {
68
bool is_6 = _test_v6(p_ip);
69
bool is_4 = _test_v4(p_ip);
70
bool is_valid = is_valid_ip_address(String::utf8(p_ip));
71
IPAddress ip(p_ip);
72
return is_6 == false && is_4 == false && ip.is_valid() == false && is_valid == false && ip.is_wildcard() == true;
73
}
74
};
75
76
TEST_CASE("[IPAddress] Wildcard and misc") {
77
ERR_PRINT_OFF;
78
79
auto test_ip = [](const char *l_ip, bool l_valid) {
80
return IPAddress(l_ip).is_wildcard() == false && l_valid == (IPTester::test_v4(l_ip, true) || IPTester::test_v6(l_ip, true));
81
};
82
83
CHECK(IPTester::test_wildcard("*"));
84
85
CHECK(test_ip("", false));
86
87
CHECK(test_ip(" ", false));
88
89
CHECK(test_ip("::", true));
90
CHECK(test_ip("0.0.0.0", true));
91
92
CHECK(test_ip("not an ip", false));
93
CHECK(test_ip("surely.not:an:ip", false));
94
95
ERR_PRINT_ON;
96
}
97
98
TEST_CASE("[IPAddress] IPv4 is_valid") {
99
ERR_PRINT_OFF;
100
101
auto test_ip = [](const char *l_ip, bool l_valid) {
102
return IPTester::test_v4(l_ip, l_valid);
103
};
104
105
// Valid IPs
106
CHECK(test_ip("127.0.0.1", true));
107
CHECK(test_ip("255.255.255.255", true));
108
CHECK(test_ip("0.0.0.0", true));
109
110
// Invalid IPs
111
CHECK(test_ip(" 127.0.0.1", false));
112
CHECK(test_ip("127.0.0.1 ", false));
113
CHECK(test_ip(" 127.0.0.1 ", false));
114
CHECK(test_ip("127.0.0.-1", false));
115
CHECK(test_ip("127.0.0.256", false));
116
CHECK(test_ip("127.0.0.", false));
117
CHECK(test_ip(".0.0.1", false));
118
CHECK(test_ip("127.0.0.1.", false));
119
CHECK(test_ip(".127.0.0.1", false));
120
CHECK(test_ip("0.127.0.0.1", false));
121
CHECK(test_ip("127.0.0.1.0", false));
122
CHECK(test_ip(".....", false));
123
CHECK(test_ip("....", false));
124
CHECK(test_ip("...", false));
125
CHECK(test_ip("..", false));
126
CHECK(test_ip(".", false));
127
CHECK(test_ip("", false));
128
ERR_PRINT_ON;
129
}
130
131
TEST_CASE("[IPAddress] IPv4 Parsing") {
132
auto test_ip = [](const char *l_ip, uint32_t l_test) {
133
l_test = BSWAP32(l_test);
134
return memcmp(IPAddress(l_ip).get_ipv4(), &l_test, 4) == 0 && IPTester::test_v4(l_ip, true);
135
};
136
CHECK(test_ip("127.0.0.1", 2130706433));
137
CHECK(test_ip("255.0.0.0", 255 << 24));
138
CHECK(test_ip("0.255.0.0", 255 << 16));
139
CHECK(test_ip("0.0.255.0", 255 << 8));
140
CHECK(test_ip("0.0.0.255", 255));
141
CHECK(test_ip("127.0.0.0", 127 << 24));
142
CHECK(test_ip("0.127.0.0", 127 << 16));
143
CHECK(test_ip("0.0.127.0", 127 << 8));
144
CHECK(test_ip("0.0.0.127", 127));
145
CHECK(test_ip("1.0.0.0", 1 << 24));
146
CHECK(test_ip("0.1.0.0", 1 << 16));
147
CHECK(test_ip("0.0.1.0", 1 << 8));
148
CHECK(test_ip("0.0.0.1", 1));
149
}
150
151
TEST_CASE("[IPAddress] IPv6 is_valid") {
152
ERR_PRINT_OFF;
153
154
auto test_ip = [](const char *l_ip, bool l_valid) {
155
return IPTester::test_v6(l_ip, l_valid);
156
};
157
158
// Valid IPs
159
CHECK(test_ip("::", true));
160
161
CHECK(test_ip("::1", true));
162
CHECK(test_ip("::1:1", true));
163
CHECK(test_ip("::1:1:1", true));
164
CHECK(test_ip("::1:1:1:1", true));
165
CHECK(test_ip("::1:1:1:1:1", true));
166
CHECK(test_ip("::1:1:1:1:1:1", true));
167
CHECK(test_ip("::1:1:1:1:1:1:1", true));
168
CHECK(test_ip("1:1:1:1:1:1:1:1", true));
169
CHECK(test_ip("1:1:1:1:1:1:1::", true));
170
CHECK(test_ip("1:1:1:1:1:1::", true));
171
CHECK(test_ip("1:1:1:1:1::", true));
172
CHECK(test_ip("1:1:1:1::", true));
173
CHECK(test_ip("1:1:1::", true));
174
CHECK(test_ip("1:1::", true));
175
CHECK(test_ip("1::", true));
176
177
CHECK(test_ip("1::1:1:1:1:1:1", true));
178
CHECK(test_ip("1:1::1:1:1:1:1", true));
179
CHECK(test_ip("1:1:1::1:1:1:1", true));
180
CHECK(test_ip("1:1:1:1::1:1:1", true));
181
CHECK(test_ip("1:1:1:1:1::1:1", true));
182
CHECK(test_ip("1:1:1:1:1:1::1", true));
183
CHECK(test_ip("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", true));
184
CHECK(test_ip("FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", true));
185
CHECK(test_ip("::ffff", true));
186
CHECK(test_ip("::FFFF", true));
187
CHECK(test_ip("ffff::", true));
188
CHECK(test_ip("FFFF::", true));
189
190
// IPv4-mapped address
191
CHECK(test_ip("::ffff:127.0.0.1", true));
192
CHECK(test_ip("::FFFF:127.0.0.1", true));
193
CHECK(test_ip("0::ffff:127.0.0.1", true));
194
CHECK(test_ip("0:0::ffff:127.0.0.1", true));
195
CHECK(test_ip("0:0:0::ffff:127.0.0.1", true));
196
CHECK(test_ip("0:0:0:0::ffff:127.0.0.1", true));
197
CHECK(test_ip("0:0:0:0:0:ffff:127.0.0.1", true));
198
199
// Invalid IPs
200
CHECK(test_ip(" ::", false));
201
CHECK(test_ip(":: ", false));
202
CHECK(test_ip("::-0", false));
203
CHECK(test_ip("1:1:1:1:1:1:1:g", false));
204
CHECK(test_ip(" 1:1:1:1:1:1:1:1", false));
205
CHECK(test_ip("1:1:1:1:1:1:1:1 ", false));
206
CHECK(test_ip(" 1:1:1:1:1:1:1:1 ", false));
207
CHECK(test_ip("1:1:1:1:1:1:1:1:1", false));
208
CHECK(test_ip("1:1:1:1:1:1:1:1::", false));
209
CHECK(test_ip("::1:1:1:1:1:1:1:1", false));
210
CHECK(test_ip("::1::1", false));
211
CHECK(test_ip(":", false));
212
CHECK(test_ip(":::", false));
213
CHECK(test_ip("::::", false));
214
CHECK(test_ip(":::::", false));
215
CHECK(test_ip("::::::", false));
216
CHECK(test_ip(":::::::", false));
217
CHECK(test_ip("::::::::", false));
218
219
// IPv4-mapped address
220
CHECK(test_ip("1::ffff:127.0.0.1", false));
221
CHECK(test_ip("::1:ffff:127.0.0.1", false));
222
CHECK(test_ip("::ffff:127.0.256.1", false));
223
CHECK(test_ip("::ffff:127.0.0.256", false));
224
CHECK(test_ip("::ffff:256.0.0.1", false));
225
CHECK(test_ip("::ffff:127.0.0.1.1", false));
226
CHECK(test_ip("::ffff:127.0.0.1.", false));
227
CHECK(test_ip("::ffff:127.0.0.", false));
228
CHECK(test_ip("::ffff:127.0.0", false));
229
CHECK(test_ip("::ffff:127.0.", false));
230
CHECK(test_ip("::ffff:127.0", false));
231
CHECK(test_ip("::ffff:127.", false));
232
CHECK(test_ip("::ffff:", false));
233
234
// This is a valid IPv6 address (non IPv4-mapped)
235
CHECK(test_ip("::ffff:127", true));
236
237
ERR_PRINT_ON;
238
}
239
240
TEST_CASE("[IPAddress] IPv6 Parsing") {
241
struct InitIP {
242
uint16_t data[8];
243
};
244
auto test_ip = [](const char *l_ip, InitIP l_test) {
245
for (int i = 0; i < 8; i++) {
246
l_test.data[i] = BSWAP16(l_test.data[i]);
247
}
248
return memcmp(IPAddress(l_ip).get_ipv6(), l_test.data, 16) == 0 && IPTester::test_v6(l_ip, true);
249
};
250
CHECK(IPAddress("::").is_valid() == true);
251
252
CHECK(test_ip("::1", { 0, 0, 0, 0, 0, 0, 0, 1 }));
253
CHECK(test_ip("::1:1", { 0, 0, 0, 0, 0, 0, 1, 1 }));
254
CHECK(test_ip("::1:1:1", { 0, 0, 0, 0, 0, 1, 1, 1 }));
255
CHECK(test_ip("::1:1:1:1", { 0, 0, 0, 0, 1, 1, 1, 1 }));
256
CHECK(test_ip("::1:1:1:1:1", { 0, 0, 0, 1, 1, 1, 1, 1 }));
257
CHECK(test_ip("::1:1:1:1:1:1", { 0, 0, 1, 1, 1, 1, 1, 1 }));
258
CHECK(test_ip("::1:1:1:1:1:1:1", { 0, 1, 1, 1, 1, 1, 1, 1 }));
259
CHECK(test_ip("1:1:1:1:1:1:1:1", { 1, 1, 1, 1, 1, 1, 1, 1 }));
260
CHECK(test_ip("1:1:1:1:1:1:1::", { 1, 1, 1, 1, 1, 1, 1, 0 }));
261
CHECK(test_ip("1:1:1:1:1:1::", { 1, 1, 1, 1, 1, 1, 0, 0 }));
262
CHECK(test_ip("1:1:1:1:1::", { 1, 1, 1, 1, 1, 0, 0, 0 }));
263
CHECK(test_ip("1:1:1:1::", { 1, 1, 1, 1, 0, 0, 0, 0 }));
264
CHECK(test_ip("1:1:1::", { 1, 1, 1, 0, 0, 0, 0, 0 }));
265
CHECK(test_ip("1:1::", { 1, 1, 0, 0, 0, 0, 0, 0 }));
266
CHECK(test_ip("1::", { 1, 0, 0, 0, 0, 0, 0, 0 }));
267
268
CHECK(test_ip("ffff::", { 0xFFFF, 0, 0, 0, 0, 0, 0, 0 }));
269
CHECK(test_ip("::ffff", { 0, 0, 0, 0, 0, 0, 0, 0xFFFF }));
270
CHECK(test_ip("::fffe:0", { 0, 0, 0, 0, 0, 0, 0xFFFE, 0 }));
271
CHECK(test_ip("0:fffe::", { 0, 0xFFFE, 0, 0, 0, 0, 0, 0 }));
272
273
// IPv4-mapped address
274
CHECK(test_ip("::ffff:127.0.0.1", { 0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1 }));
275
CHECK(test_ip("::FFFF:127.0.0.1", { 0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1 }));
276
CHECK(test_ip("0::ffff:127.0.0.1", { 0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1 }));
277
CHECK(test_ip("0:0::ffff:127.0.0.1", { 0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1 }));
278
CHECK(test_ip("0:0:0::ffff:127.0.0.1", { 0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1 }));
279
CHECK(test_ip("0:0:0:0::ffff:127.0.0.1", { 0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1 }));
280
CHECK(test_ip("0:0:0:0:0:ffff:127.0.0.1", { 0, 0, 0, 0, 0, 0xFFFF, 0x7F00, 1 }));
281
}
282
283
} // namespace TestIPAddress
284
285