Line | Source Code | Coverage |
---|
1 | | - |
2 | | - |
3 | namespace QIPAddressUtils { | - |
4 | | - |
5 | static QString number(quint8 val, int base = 10) | - |
6 | { | - |
7 | QChar zero(0x30); | - |
8 | return val ? qulltoa(val, base, zero) : zero; executed: return val ? qulltoa(val, base, zero) : zero; Execution Count:3480 | 3480 |
9 | } | - |
10 | | - |
11 | typedef QVarLengthArray<char, 64> Buffer; | - |
12 | static bool checkedToAscii(Buffer &buffer, const QChar *begin, const QChar *end) | - |
13 | { | - |
14 | const ushort *const ubegin = reinterpret_cast<const ushort *>(begin); | - |
15 | const ushort *const uend = reinterpret_cast<const ushort *>(end); | - |
16 | const ushort *src = ubegin; | - |
17 | | - |
18 | buffer.resize(uend - ubegin + 1); | - |
19 | char *dst = buffer.data(); | - |
20 | | - |
21 | while (src != uend) { evaluated: src != uend yes Evaluation Count:262201 | yes Evaluation Count:17475 |
| 17475-262201 |
22 | if (*src >= 0x7f) evaluated: *src >= 0x7f yes Evaluation Count:199 | yes Evaluation Count:262034 |
| 199-262034 |
23 | return false; executed: return false; Execution Count:199 | 199 |
24 | *dst++ = *src++; | - |
25 | } executed: } Execution Count:262069 | 262069 |
26 | *dst = '\0'; | - |
27 | return true; executed: return true; Execution Count:17476 | 17476 |
28 | } | - |
29 | | - |
30 | static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptLeadingZero); | - |
31 | bool parseIp4(IPv4Address &address, const QChar *begin, const QChar *end) | - |
32 | { | - |
33 | qt_noop(); | - |
34 | Buffer buffer; | - |
35 | if (!checkedToAscii(buffer, begin, end)) evaluated: !checkedToAscii(buffer, begin, end) yes Evaluation Count:199 | yes Evaluation Count:17140 |
| 199-17140 |
36 | return false; executed: return false; Execution Count:199 | 199 |
37 | | - |
38 | const char *ptr = buffer.data(); | - |
39 | return parseIp4Internal(address, ptr, true); executed: return parseIp4Internal(address, ptr, true); Execution Count:17140 | 17140 |
40 | } | - |
41 | | - |
42 | static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptLeadingZero) | - |
43 | { | - |
44 | address = 0; | - |
45 | int dotCount = 0; | - |
46 | while (dotCount < 4) { partially evaluated: dotCount < 4 yes Evaluation Count:22535 | no Evaluation Count:0 |
| 0-22535 |
47 | if (!acceptLeadingZero && *ptr == '0' && evaluated: !acceptLeadingZero yes Evaluation Count:148 | yes Evaluation Count:22383 |
evaluated: *ptr == '0' yes Evaluation Count:32 | yes Evaluation Count:116 |
| 32-22383 |
48 | ptr[1] != '.' && ptr[1] != '\0') evaluated: ptr[1] != '.' yes Evaluation Count:3 | yes Evaluation Count:29 |
partially evaluated: ptr[1] != '\0' no Evaluation Count:0 | yes Evaluation Count:3 |
| 0-29 |
49 | return false; never executed: return false; | 0 |
50 | | - |
51 | const char *endptr; | - |
52 | bool ok; | - |
53 | quint64 ll = qstrtoull(ptr, &endptr, 0, &ok); | - |
54 | quint32 x = ll; | - |
55 | if (!ok || endptr == ptr || ll != x) evaluated: !ok yes Evaluation Count:15311 | yes Evaluation Count:7137 |
partially evaluated: endptr == ptr no Evaluation Count:0 | yes Evaluation Count:7137 |
partially evaluated: ll != x no Evaluation Count:0 | yes Evaluation Count:7137 |
| 0-15311 |
56 | return false; executed: return false; Execution Count:15298 | 15298 |
57 | | - |
58 | if (*endptr == '.' || dotCount == 3) { evaluated: *endptr == '.' yes Evaluation Count:5317 | yes Evaluation Count:1821 |
evaluated: dotCount == 3 yes Evaluation Count:1770 | yes Evaluation Count:51 |
| 51-5317 |
59 | if (x & ~0xff) evaluated: x & ~0xff yes Evaluation Count:3 | yes Evaluation Count:7083 |
| 3-7083 |
60 | return false; executed: return false; Execution Count:3 | 3 |
61 | address <<= 8; | - |
62 | } else if (dotCount == 2) { evaluated: dotCount == 2 yes Evaluation Count:12 | yes Evaluation Count:39 |
executed: } Execution Count:7083 | 12-7083 |
63 | if (x & ~0xffff) partially evaluated: x & ~0xffff no Evaluation Count:0 | yes Evaluation Count:12 |
| 0-12 |
64 | return false; never executed: return false; | 0 |
65 | address <<= 16; | - |
66 | } else if (dotCount == 1) { executed: } Execution Count:12 evaluated: dotCount == 1 yes Evaluation Count:14 | yes Evaluation Count:25 |
| 12-25 |
67 | if (x & ~0xffffff) partially evaluated: x & ~0xffffff no Evaluation Count:0 | yes Evaluation Count:14 |
| 0-14 |
68 | return false; never executed: return false; | 0 |
69 | address <<= 24; | - |
70 | } executed: } Execution Count:14 | 14 |
71 | address |= x; | - |
72 | | - |
73 | if (dotCount == 3 && *endptr != '\0') evaluated: dotCount == 3 yes Evaluation Count:1776 | yes Evaluation Count:5359 |
evaluated: *endptr != '\0' yes Evaluation Count:19 | yes Evaluation Count:1757 |
| 19-5359 |
74 | return false; executed: return false; Execution Count:19 | 19 |
75 | else if (dotCount == 3 || *endptr == '\0') evaluated: dotCount == 3 yes Evaluation Count:1757 | yes Evaluation Count:5359 |
evaluated: *endptr == '\0' yes Evaluation Count:5 | yes Evaluation Count:5354 |
| 5-5359 |
76 | return true; executed: return true; Execution Count:1762 | 1762 |
77 | ++dotCount; | - |
78 | ptr = endptr + 1; | - |
79 | } executed: } Execution Count:5354 | 5354 |
80 | return false; never executed: return false; | 0 |
81 | } | - |
82 | | - |
83 | void toString(QString &appendTo, IPv4Address address) | - |
84 | { | - |
85 | | - |
86 | | - |
87 | appendTo += number(address >> 24) | - |
88 | % QLatin1Char('.') | - |
89 | % number(address >> 16) | - |
90 | % QLatin1Char('.') | - |
91 | % number(address >> 8) | - |
92 | % QLatin1Char('.') | - |
93 | % number(address); | - |
94 | } executed: } Execution Count:870 | 870 |
95 | | - |
96 | bool parseIp6(IPv6Address &address, const QChar *begin, const QChar *end) | - |
97 | { | - |
98 | qt_noop(); | - |
99 | Buffer buffer; | - |
100 | if (!checkedToAscii(buffer, begin, end)) partially evaluated: !checkedToAscii(buffer, begin, end) no Evaluation Count:0 | yes Evaluation Count:336 |
| 0-336 |
101 | return false; never executed: return false; | 0 |
102 | | - |
103 | const char *ptr = buffer.data(); | - |
104 | | - |
105 | | - |
106 | int colonCount = 0; | - |
107 | int dotCount = 0; | - |
108 | while (*ptr) { evaluated: *ptr yes Evaluation Count:5194 | yes Evaluation Count:336 |
| 336-5194 |
109 | if (*ptr == ':') evaluated: *ptr == ':' yes Evaluation Count:1312 | yes Evaluation Count:3882 |
| 1312-3882 |
110 | ++colonCount; executed: ++colonCount; Execution Count:1312 | 1312 |
111 | if (*ptr == '.') evaluated: *ptr == '.' yes Evaluation Count:165 | yes Evaluation Count:5029 |
| 165-5029 |
112 | ++dotCount; executed: ++dotCount; Execution Count:165 | 165 |
113 | ++ptr; | - |
114 | } executed: } Execution Count:5194 | 5194 |
115 | | - |
116 | if (dotCount != 0 && dotCount != 3) evaluated: dotCount != 0 yes Evaluation Count:55 | yes Evaluation Count:281 |
evaluated: dotCount != 3 yes Evaluation Count:5 | yes Evaluation Count:50 |
| 5-281 |
117 | return false; executed: return false; Execution Count:5 | 5 |
118 | | - |
119 | memset(address, 0, sizeof address); | - |
120 | if (colonCount == 2 && end - begin == 2) evaluated: colonCount == 2 yes Evaluation Count:123 | yes Evaluation Count:208 |
evaluated: end - begin == 2 yes Evaluation Count:14 | yes Evaluation Count:109 |
| 14-208 |
121 | return true; executed: return true; Execution Count:14 | 14 |
122 | | - |
123 | | - |
124 | int zeroWordsToFill; | - |
125 | ptr = buffer.data(); | - |
126 | | - |
127 | | - |
128 | | - |
129 | if ((ptr[0] == ':' && ptr[1] == ':') || evaluated: ptr[0] == ':' yes Evaluation Count:115 | yes Evaluation Count:202 |
evaluated: ptr[1] == ':' yes Evaluation Count:110 | yes Evaluation Count:5 |
| 5-202 |
130 | (ptr[end - begin - 2] == ':' && ptr[end - begin - 1] == ':')) { evaluated: ptr[end - begin - 2] == ':' yes Evaluation Count:88 | yes Evaluation Count:119 |
evaluated: ptr[end - begin - 1] == ':' yes Evaluation Count:51 | yes Evaluation Count:37 |
| 37-119 |
131 | zeroWordsToFill = 9 - colonCount; | - |
132 | } else if (colonCount < 2 || colonCount > 7) { evaluated: colonCount < 2 yes Evaluation Count:12 | yes Evaluation Count:144 |
evaluated: colonCount > 7 yes Evaluation Count:2 | yes Evaluation Count:142 |
executed: } Execution Count:161 | 2-161 |
133 | return false; executed: return false; Execution Count:14 | 14 |
134 | } else { | - |
135 | zeroWordsToFill = 8 - colonCount; | - |
136 | } executed: } Execution Count:142 | 142 |
137 | if (dotCount) evaluated: dotCount yes Evaluation Count:47 | yes Evaluation Count:256 |
| 47-256 |
138 | --zeroWordsToFill; executed: --zeroWordsToFill; Execution Count:47 | 47 |
139 | | - |
140 | int pos = 0; | - |
141 | while (pos < 15) { evaluated: pos < 15 yes Evaluation Count:1349 | yes Evaluation Count:45 |
| 45-1349 |
142 | const char *endptr; | - |
143 | bool ok; | - |
144 | quint64 ll = qstrtoull(ptr, &endptr, 16, &ok); | - |
145 | quint16 x = ll; | - |
146 | | - |
147 | if (ptr == endptr) { evaluated: ptr == endptr yes Evaluation Count:258 | yes Evaluation Count:1091 |
| 258-1091 |
148 | | - |
149 | if (zeroWordsToFill < 1) evaluated: zeroWordsToFill < 1 yes Evaluation Count:23 | yes Evaluation Count:235 |
| 23-235 |
150 | return false; executed: return false; Execution Count:23 | 23 |
151 | if (pos == 0 || pos == colonCount * 2) { evaluated: pos == 0 yes Evaluation Count:112 | yes Evaluation Count:123 |
partially evaluated: pos == colonCount * 2 no Evaluation Count:0 | yes Evaluation Count:123 |
| 0-123 |
152 | if (ptr[0] == '\0' || ptr[1] != ':') partially evaluated: ptr[0] == '\0' no Evaluation Count:0 | yes Evaluation Count:112 |
evaluated: ptr[1] != ':' yes Evaluation Count:2 | yes Evaluation Count:110 |
| 0-112 |
153 | return false; executed: return false; Execution Count:2 | 2 |
154 | ++ptr; | - |
155 | } executed: } Execution Count:110 | 110 |
156 | pos += zeroWordsToFill * 2; | - |
157 | zeroWordsToFill = 0; | - |
158 | ++ptr; | - |
159 | continue; executed: continue; Execution Count:233 | 233 |
160 | } | - |
161 | if (!ok || ll != x) partially evaluated: !ok no Evaluation Count:0 | yes Evaluation Count:1091 |
evaluated: ll != x yes Evaluation Count:4 | yes Evaluation Count:1087 |
| 0-1091 |
162 | return false; executed: return false; Execution Count:4 | 4 |
163 | | - |
164 | if (*endptr == '.') { evaluated: *endptr == '.' yes Evaluation Count:41 | yes Evaluation Count:1046 |
| 41-1046 |
165 | | - |
166 | | - |
167 | if (pos != 12) evaluated: pos != 12 yes Evaluation Count:4 | yes Evaluation Count:37 |
| 4-37 |
168 | return false; executed: return false; Execution Count:4 | 4 |
169 | | - |
170 | IPv4Address ip4; | - |
171 | if (!parseIp4Internal(ip4, ptr, false)) partially evaluated: !parseIp4Internal(ip4, ptr, false) no Evaluation Count:0 | yes Evaluation Count:37 |
| 0-37 |
172 | return false; never executed: return false; | 0 |
173 | | - |
174 | address[12] = ip4 >> 24; | - |
175 | address[13] = ip4 >> 16; | - |
176 | address[14] = ip4 >> 8; | - |
177 | address[15] = ip4; | - |
178 | return true; executed: return true; Execution Count:37 | 37 |
179 | } | - |
180 | | - |
181 | address[pos++] = x >> 8; | - |
182 | address[pos++] = x & 0xff; | - |
183 | | - |
184 | if (*endptr == '\0') evaluated: *endptr == '\0' yes Evaluation Count:167 | yes Evaluation Count:879 |
| 167-879 |
185 | break; executed: break; Execution Count:167 | 167 |
186 | if (*endptr != ':') evaluated: *endptr != ':' yes Evaluation Count:21 | yes Evaluation Count:858 |
| 21-858 |
187 | return false; executed: return false; Execution Count:21 | 21 |
188 | ptr = endptr + 1; | - |
189 | } executed: } Execution Count:858 | 858 |
190 | return pos == 16; executed: return pos == 16; Execution Count:212 | 212 |
191 | } | - |
192 | | - |
193 | static inline QChar toHex(uchar c) | - |
194 | { | - |
195 | return ushort(c > 9 ? c + 'a' - 0xA : c + '0'); executed: return ushort(c > 9 ? c + 'a' - 0xA : c + '0'); Execution Count:2184 | 2184 |
196 | } | - |
197 | | - |
198 | void toString(QString &appendTo, IPv6Address address) | - |
199 | { | - |
200 | | - |
201 | | - |
202 | | - |
203 | | - |
204 | | - |
205 | | - |
206 | | - |
207 | static const int Ip6AddressMaxLen = sizeof "1111:2222:3333:4444:5555:6666:7777:8888"; | - |
208 | static const int Ip6WithIp4AddressMaxLen = sizeof "::ffff:255.255.255.255"; | - |
209 | | - |
210 | | - |
211 | const quint64 zeroes[] = { 0, 0 }; | - |
212 | bool embeddedIp4 = false; | - |
213 | | - |
214 | | - |
215 | | - |
216 | | - |
217 | if (memcmp(address, zeroes, 10) == 0) { evaluated: memcmp(address, zeroes, 10) == 0 yes Evaluation Count:84 | yes Evaluation Count:133 |
| 84-133 |
218 | if (address[10] == 0xff && address[11] == 0xff) { evaluated: address[10] == 0xff yes Evaluation Count:17 | yes Evaluation Count:67 |
partially evaluated: address[11] == 0xff yes Evaluation Count:17 | no Evaluation Count:0 |
| 0-67 |
219 | embeddedIp4 = true; | - |
220 | } else if (address[10] == 0 && address[11] == 0) { partially evaluated: address[10] == 0 yes Evaluation Count:67 | no Evaluation Count:0 |
partially evaluated: address[11] == 0 yes Evaluation Count:67 | no Evaluation Count:0 |
executed: } Execution Count:17 | 0-67 |
221 | if (address[12] != 0 || address[13] != 0 || address[14] != 0) { evaluated: address[12] != 0 yes Evaluation Count:5 | yes Evaluation Count:62 |
partially evaluated: address[13] != 0 no Evaluation Count:0 | yes Evaluation Count:62 |
partially evaluated: address[14] != 0 no Evaluation Count:0 | yes Evaluation Count:62 |
| 0-62 |
222 | embeddedIp4 = true; | - |
223 | } else if (address[15] == 0) { executed: } Execution Count:5 evaluated: address[15] == 0 yes Evaluation Count:31 | yes Evaluation Count:31 |
| 5-31 |
224 | appendTo.append(QLatin1String("::")); | - |
225 | return; executed: return; Execution Count:31 | 31 |
226 | } | - |
227 | } | - |
228 | } | - |
229 | | - |
230 | | - |
231 | appendTo.reserve(appendTo.size() + | - |
232 | (embeddedIp4 ? Ip6WithIp4AddressMaxLen : Ip6AddressMaxLen)); | - |
233 | | - |
234 | | - |
235 | int zeroRunLength = 0; | - |
236 | int zeroRunOffset = 0; | - |
237 | for (int i = 0; i < 16; i += 2) { evaluated: i < 16 yes Evaluation Count:827 | yes Evaluation Count:186 |
| 186-827 |
238 | if (address[i] == 0 && address[i + 1] == 0) { evaluated: address[i] == 0 yes Evaluation Count:438 | yes Evaluation Count:389 |
evaluated: address[i + 1] == 0 yes Evaluation Count:196 | yes Evaluation Count:242 |
| 196-438 |
239 | | - |
240 | int j; | - |
241 | for (j = i; j < 16; j += 2) { evaluated: j < 16 yes Evaluation Count:869 | yes Evaluation Count:43 |
| 43-869 |
242 | if (address[j] != 0 || address[j+1] != 0) evaluated: address[j] != 0 yes Evaluation Count:59 | yes Evaluation Count:810 |
evaluated: address[j+1] != 0 yes Evaluation Count:94 | yes Evaluation Count:716 |
| 59-810 |
243 | break; executed: break; Execution Count:153 | 153 |
244 | } executed: } Execution Count:716 | 716 |
245 | | - |
246 | if (j - i > zeroRunLength) { evaluated: j - i > zeroRunLength yes Evaluation Count:178 | yes Evaluation Count:18 |
| 18-178 |
247 | zeroRunLength = j - i; | - |
248 | zeroRunOffset = i; | - |
249 | i = j; | - |
250 | } executed: } Execution Count:178 | 178 |
251 | } executed: } Execution Count:196 | 196 |
252 | } executed: } Execution Count:827 | 827 |
253 | | - |
254 | const QChar colon = ushort(':'); | - |
255 | if (zeroRunLength < 4) evaluated: zeroRunLength < 4 yes Evaluation Count:47 | yes Evaluation Count:139 |
| 47-139 |
256 | zeroRunOffset = -1; executed: zeroRunOffset = -1; Execution Count:47 | 47 |
257 | else if (zeroRunOffset == 0) evaluated: zeroRunOffset == 0 yes Evaluation Count:53 | yes Evaluation Count:86 |
| 53-86 |
258 | appendTo.append(colon); executed: appendTo.append(colon); Execution Count:53 | 53 |
259 | | - |
260 | for (int i = 0; i < 16; i += 2) { evaluated: i < 16 yes Evaluation Count:948 | yes Evaluation Count:164 |
| 164-948 |
261 | if (i == zeroRunOffset) { evaluated: i == zeroRunOffset yes Evaluation Count:139 | yes Evaluation Count:809 |
| 139-809 |
262 | appendTo.append(colon); | - |
263 | i += zeroRunLength - 2; | - |
264 | continue; executed: continue; Execution Count:139 | 139 |
265 | } | - |
266 | | - |
267 | if (i == 12 && embeddedIp4) { evaluated: i == 12 yes Evaluation Count:122 | yes Evaluation Count:687 |
evaluated: embeddedIp4 yes Evaluation Count:22 | yes Evaluation Count:100 |
| 22-687 |
268 | IPv4Address ip4 = address[12] << 24 | | - |
269 | address[13] << 16 | | - |
270 | address[14] << 8 | | - |
271 | address[15]; | - |
272 | toString(appendTo, ip4); | - |
273 | return; executed: return; Execution Count:22 | 22 |
274 | } | - |
275 | | - |
276 | if (address[i]) { evaluated: address[i] yes Evaluation Count:408 | yes Evaluation Count:379 |
| 379-408 |
277 | if (address[i] >> 4) { evaluated: address[i] >> 4 yes Evaluation Count:363 | yes Evaluation Count:45 |
| 45-363 |
278 | appendTo.append(toHex(address[i] >> 4)); | - |
279 | appendTo.append(toHex(address[i] & 0xf)); | - |
280 | appendTo.append(toHex(address[i + 1] >> 4)); | - |
281 | appendTo.append(toHex(address[i + 1] & 0xf)); | - |
282 | } else if (address[i] & 0xf) { executed: } Execution Count:363 partially evaluated: address[i] & 0xf yes Evaluation Count:45 | no Evaluation Count:0 |
| 0-363 |
283 | appendTo.append(toHex(address[i] & 0xf)); | - |
284 | appendTo.append(toHex(address[i + 1] >> 4)); | - |
285 | appendTo.append(toHex(address[i + 1] & 0xf)); | - |
286 | } executed: } Execution Count:45 | 45 |
287 | } else if (address[i + 1] >> 4) { evaluated: address[i + 1] >> 4 yes Evaluation Count:218 | yes Evaluation Count:161 |
| 161-218 |
288 | appendTo.append(toHex(address[i + 1] >> 4)); | - |
289 | appendTo.append(toHex(address[i + 1] & 0xf)); | - |
290 | } else { executed: } Execution Count:218 | 218 |
291 | appendTo.append(toHex(address[i + 1] & 0xf)); | - |
292 | } executed: } Execution Count:161 | 161 |
293 | | - |
294 | if (i != 14) evaluated: i != 14 yes Evaluation Count:654 | yes Evaluation Count:133 |
| 133-654 |
295 | appendTo.append(colon); executed: appendTo.append(colon); Execution Count:654 | 654 |
296 | } executed: } Execution Count:787 | 787 |
297 | } executed: } Execution Count:164 | 164 |
298 | | - |
299 | } | - |
300 | | - |
301 | | - |
| | |