Line | Source Code | Coverage |
---|
1 | /**************************************************************************** | - |
2 | ** | - |
3 | ** Copyright (C) 2012 Intel Corporation | - |
4 | ** Contact: http://www.qt-project.org/legal | - |
5 | ** | - |
6 | ** This file is part of the QtCore module of the Qt Toolkit. | - |
7 | ** | - |
8 | ** $QT_BEGIN_LICENSE:LGPL$ | - |
9 | ** Commercial License Usage | - |
10 | ** Licensees holding valid commercial Qt licenses may use this file in | - |
11 | ** accordance with the commercial license agreement provided with the | - |
12 | ** Software or, alternatively, in accordance with the terms contained in | - |
13 | ** a written agreement between you and Digia. For licensing terms and | - |
14 | ** conditions see http://qt.digia.com/licensing. For further information | - |
15 | ** use the contact form at http://qt.digia.com/contact-us. | - |
16 | ** | - |
17 | ** GNU Lesser General Public License Usage | - |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser | - |
19 | ** General Public License version 2.1 as published by the Free Software | - |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the | - |
21 | ** packaging of this file. Please review the following information to | - |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements | - |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - |
24 | ** | - |
25 | ** In addition, as a special exception, Digia gives you certain additional | - |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception | - |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - |
28 | ** | - |
29 | ** GNU General Public License Usage | - |
30 | ** Alternatively, this file may be used under the terms of the GNU | - |
31 | ** General Public License version 3.0 as published by the Free Software | - |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the | - |
33 | ** packaging of this file. Please review the following information to | - |
34 | ** ensure the GNU General Public License version 3.0 requirements will be | - |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. | - |
36 | ** | - |
37 | ** | - |
38 | ** $QT_END_LICENSE$ | - |
39 | ** | - |
40 | ****************************************************************************/ | - |
41 | | - |
42 | #include "qurl.h" | - |
43 | | - |
44 | QT_BEGIN_NAMESPACE | - |
45 | | - |
46 | // ### move to qurl_p.h | - |
47 | enum EncodingAction { | - |
48 | DecodeCharacter = 0, | - |
49 | LeaveCharacter = 1, | - |
50 | EncodeCharacter = 2 | - |
51 | }; | - |
52 | | - |
53 | // From RFC 3896, Appendix A Collected ABNF for URI | - |
54 | // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" | - |
55 | // reserved = gen-delims / sub-delims | - |
56 | // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" | - |
57 | // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" | - |
58 | // / "*" / "+" / "," / ";" / "=" | - |
59 | static const uchar defaultActionTable[96] = { | - |
60 | 2, // space | - |
61 | 1, // '!' (sub-delim) | - |
62 | 2, // '"' | - |
63 | 1, // '#' (gen-delim) | - |
64 | 1, // '$' (gen-delim) | - |
65 | 2, // '%' (percent) | - |
66 | 1, // '&' (gen-delim) | - |
67 | 1, // "'" (sub-delim) | - |
68 | 1, // '(' (sub-delim) | - |
69 | 1, // ')' (sub-delim) | - |
70 | 1, // '*' (sub-delim) | - |
71 | 1, // '+' (sub-delim) | - |
72 | 1, // ',' (sub-delim) | - |
73 | 0, // '-' (unreserved) | - |
74 | 0, // '.' (unreserved) | - |
75 | 1, // '/' (gen-delim) | - |
76 | | - |
77 | 0, 0, 0, 0, 0, // '0' to '4' (unreserved) | - |
78 | 0, 0, 0, 0, 0, // '5' to '9' (unreserved) | - |
79 | 1, // ':' (gen-delim) | - |
80 | 1, // ';' (sub-delim) | - |
81 | 2, // '<' | - |
82 | 1, // '=' (sub-delim) | - |
83 | 2, // '>' | - |
84 | 1, // '?' (gen-delim) | - |
85 | | - |
86 | 1, // '@' (gen-delim) | - |
87 | 0, 0, 0, 0, 0, // 'A' to 'E' (unreserved) | - |
88 | 0, 0, 0, 0, 0, // 'F' to 'J' (unreserved) | - |
89 | 0, 0, 0, 0, 0, // 'K' to 'O' (unreserved) | - |
90 | 0, 0, 0, 0, 0, // 'P' to 'T' (unreserved) | - |
91 | 0, 0, 0, 0, 0, 0, // 'U' to 'Z' (unreserved) | - |
92 | 1, // '[' (gen-delim) | - |
93 | 2, // '\' | - |
94 | 1, // ']' (gen-delim) | - |
95 | 2, // '^' | - |
96 | 0, // '_' (unreserved) | - |
97 | | - |
98 | 2, // '`' | - |
99 | 0, 0, 0, 0, 0, // 'a' to 'e' (unreserved) | - |
100 | 0, 0, 0, 0, 0, // 'f' to 'j' (unreserved) | - |
101 | 0, 0, 0, 0, 0, // 'k' to 'o' (unreserved) | - |
102 | 0, 0, 0, 0, 0, // 'p' to 't' (unreserved) | - |
103 | 0, 0, 0, 0, 0, 0, // 'u' to 'z' (unreserved) | - |
104 | 2, // '{' | - |
105 | 2, // '|' | - |
106 | 2, // '}' | - |
107 | 0, // '~' (unreserved) | - |
108 | | - |
109 | 2 // BSKP | - |
110 | }; | - |
111 | | - |
112 | // mask tables, in negative polarity | - |
113 | // 0x00 if it belongs to this category | - |
114 | // 0xff if it doesn't | - |
115 | | - |
116 | static const uchar delimsMask[96] = { | - |
117 | 0xff, // space | - |
118 | 0x00, // '!' (sub-delim) | - |
119 | 0xff, // '"' | - |
120 | 0x00, // '#' (gen-delim) | - |
121 | 0x00, // '$' (gen-delim) | - |
122 | 0xff, // '%' (percent) | - |
123 | 0x00, // '&' (gen-delim) | - |
124 | 0x00, // "'" (sub-delim) | - |
125 | 0x00, // '(' (sub-delim) | - |
126 | 0x00, // ')' (sub-delim) | - |
127 | 0x00, // '*' (sub-delim) | - |
128 | 0x00, // '+' (sub-delim) | - |
129 | 0x00, // ',' (sub-delim) | - |
130 | 0xff, // '-' (unreserved) | - |
131 | 0xff, // '.' (unreserved) | - |
132 | 0x00, // '/' (gen-delim) | - |
133 | | - |
134 | 0xff, 0xff, 0xff, 0xff, 0xff, // '0' to '4' (unreserved) | - |
135 | 0xff, 0xff, 0xff, 0xff, 0xff, // '5' to '9' (unreserved) | - |
136 | 0x00, // ':' (gen-delim) | - |
137 | 0x00, // ';' (sub-delim) | - |
138 | 0xff, // '<' | - |
139 | 0x00, // '=' (sub-delim) | - |
140 | 0xff, // '>' | - |
141 | 0x00, // '?' (gen-delim) | - |
142 | | - |
143 | 0x00, // '@' (gen-delim) | - |
144 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' to 'E' (unreserved) | - |
145 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'F' to 'J' (unreserved) | - |
146 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'K' to 'O' (unreserved) | - |
147 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' to 'T' (unreserved) | - |
148 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'U' to 'Z' (unreserved) | - |
149 | 0x00, // '[' (gen-delim) | - |
150 | 0xff, // '\' | - |
151 | 0x00, // ']' (gen-delim) | - |
152 | 0xff, // '^' | - |
153 | 0xff, // '_' (unreserved) | - |
154 | | - |
155 | 0xff, // '`' | - |
156 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' to 'e' (unreserved) | - |
157 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'f' to 'j' (unreserved) | - |
158 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'k' to 'o' (unreserved) | - |
159 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' to 't' (unreserved) | - |
160 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'u' to 'z' (unreserved) | - |
161 | 0xff, // '{' | - |
162 | 0xff, // '|' | - |
163 | 0xff, // '}' | - |
164 | 0xff, // '~' (unreserved) | - |
165 | | - |
166 | 0xff // BSKP | - |
167 | }; | - |
168 | | - |
169 | static const uchar reservedMask[96] = { | - |
170 | 0xff, // space | - |
171 | 0xff, // '!' (sub-delim) | - |
172 | 0x00, // '"' | - |
173 | 0xff, // '#' (gen-delim) | - |
174 | 0xff, // '$' (gen-delim) | - |
175 | 0xff, // '%' (percent) | - |
176 | 0xff, // '&' (gen-delim) | - |
177 | 0xff, // "'" (sub-delim) | - |
178 | 0xff, // '(' (sub-delim) | - |
179 | 0xff, // ')' (sub-delim) | - |
180 | 0xff, // '*' (sub-delim) | - |
181 | 0xff, // '+' (sub-delim) | - |
182 | 0xff, // ',' (sub-delim) | - |
183 | 0xff, // '-' (unreserved) | - |
184 | 0xff, // '.' (unreserved) | - |
185 | 0xff, // '/' (gen-delim) | - |
186 | | - |
187 | 0xff, 0xff, 0xff, 0xff, 0xff, // '0' to '4' (unreserved) | - |
188 | 0xff, 0xff, 0xff, 0xff, 0xff, // '5' to '9' (unreserved) | - |
189 | 0xff, // ':' (gen-delim) | - |
190 | 0xff, // ';' (sub-delim) | - |
191 | 0x00, // '<' | - |
192 | 0xff, // '=' (sub-delim) | - |
193 | 0x00, // '>' | - |
194 | 0xff, // '?' (gen-delim) | - |
195 | | - |
196 | 0xff, // '@' (gen-delim) | - |
197 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' to 'E' (unreserved) | - |
198 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'F' to 'J' (unreserved) | - |
199 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'K' to 'O' (unreserved) | - |
200 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' to 'T' (unreserved) | - |
201 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'U' to 'Z' (unreserved) | - |
202 | 0xff, // '[' (gen-delim) | - |
203 | 0x00, // '\' | - |
204 | 0xff, // ']' (gen-delim) | - |
205 | 0x00, // '^' | - |
206 | 0xff, // '_' (unreserved) | - |
207 | | - |
208 | 0x00, // '`' | - |
209 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' to 'e' (unreserved) | - |
210 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'f' to 'j' (unreserved) | - |
211 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'k' to 'o' (unreserved) | - |
212 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' to 't' (unreserved) | - |
213 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'u' to 'z' (unreserved) | - |
214 | 0x00, // '{' | - |
215 | 0x00, // '|' | - |
216 | 0x00, // '}' | - |
217 | 0xff, // '~' (unreserved) | - |
218 | | - |
219 | 0xff // BSKP | - |
220 | }; | - |
221 | | - |
222 | static inline bool isHex(ushort c) | - |
223 | { | - |
224 | return (c >= 'a' && c <= 'f') || executed: return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9'); Execution Count:2640 | 2640 |
225 | (c >= 'A' && c <= 'F') || executed: return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9'); Execution Count:2640 | 2640 |
226 | (c >= '0' && c <= '9'); executed: return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9'); Execution Count:2640 | 2640 |
227 | } | - |
228 | | - |
229 | static inline bool isUpperHex(ushort c) | - |
230 | { | - |
231 | // undefined behaviour if c isn't an hex char! | - |
232 | return c < 0x60; executed: return c < 0x60; Execution Count:1563 | 1563 |
233 | } | - |
234 | | - |
235 | static inline ushort toUpperHex(ushort c) | - |
236 | { | - |
237 | return isUpperHex(c) ? c : c - 0x20; executed: return isUpperHex(c) ? c : c - 0x20; Execution Count:240 | 240 |
238 | } | - |
239 | | - |
240 | static inline ushort decodeNibble(ushort c) | - |
241 | { | - |
242 | return c >= 'a' ? c - 'a' + 0xA : executed: return c >= 'a' ? c - 'a' + 0xA : c >= 'A' ? c - 'A' + 0xA : c - '0'; Execution Count:2608 | 2608 |
243 | c >= 'A' ? c - 'A' + 0xA : c - '0'; executed: return c >= 'a' ? c - 'a' + 0xA : c >= 'A' ? c - 'A' + 0xA : c - '0'; Execution Count:2608 | 2608 |
244 | } | - |
245 | | - |
246 | // if the sequence at input is 2*HEXDIG, returns its decoding | - |
247 | // returns -1 if it isn't. | - |
248 | // assumes that the range has been checked already | - |
249 | static inline ushort decodePercentEncoding(const ushort *input) | - |
250 | { | - |
251 | ushort c1 = input[1]; executed (the execution status of this line is deduced): ushort c1 = input[1]; | - |
252 | ushort c2 = input[2]; executed (the execution status of this line is deduced): ushort c2 = input[2]; | - |
253 | if (!isHex(c1) || !isHex(c2)) evaluated: !isHex(c1) yes Evaluation Count:22 | yes Evaluation Count:1309 |
evaluated: !isHex(c2) yes Evaluation Count:18 | yes Evaluation Count:1291 |
| 18-1309 |
254 | return ushort(-1); executed: return ushort(-1); Execution Count:40 | 40 |
255 | return decodeNibble(c1) << 4 | decodeNibble(c2); executed: return decodeNibble(c1) << 4 | decodeNibble(c2); Execution Count:1291 | 1291 |
256 | } | - |
257 | | - |
258 | static inline ushort encodeNibble(ushort c) | - |
259 | { | - |
260 | static const uchar hexnumbers[] = "0123456789ABCDEF"; | - |
261 | return hexnumbers[c & 0xf]; executed: return hexnumbers[c & 0xf]; Execution Count:4327 | 4327 |
262 | } | - |
263 | | - |
264 | static void ensureDetached(QString &result, ushort *&output, const ushort *begin, const ushort *input, const ushort *end, | - |
265 | int add = 0) | - |
266 | { | - |
267 | if (!output) { evaluated: !output yes Evaluation Count:1376 | yes Evaluation Count:1319 |
| 1319-1376 |
268 | // now detach | - |
269 | // create enough space if the rest of the string needed to be percent-encoded | - |
270 | int charsProcessed = input - begin; executed (the execution status of this line is deduced): int charsProcessed = input - begin; | - |
271 | int charsRemaining = end - input; executed (the execution status of this line is deduced): int charsRemaining = end - input; | - |
272 | int spaceNeeded = end - begin + 2 * charsRemaining + add; executed (the execution status of this line is deduced): int spaceNeeded = end - begin + 2 * charsRemaining + add; | - |
273 | int origSize = result.size(); executed (the execution status of this line is deduced): int origSize = result.size(); | - |
274 | result.resize(origSize + spaceNeeded); executed (the execution status of this line is deduced): result.resize(origSize + spaceNeeded); | - |
275 | | - |
276 | // we know that resize() above detached, so we bypass the reference count check | - |
277 | output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData())) executed (the execution status of this line is deduced): output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData())) | - |
278 | + origSize; executed (the execution status of this line is deduced): + origSize; | - |
279 | | - |
280 | // copy the chars we've already processed | - |
281 | int i; executed (the execution status of this line is deduced): int i; | - |
282 | for (i = 0; i < charsProcessed; ++i) evaluated: i < charsProcessed yes Evaluation Count:10159 | yes Evaluation Count:1376 |
| 1376-10159 |
283 | output[i] = begin[i]; executed: output[i] = begin[i]; Execution Count:10159 | 10159 |
284 | output += i; executed (the execution status of this line is deduced): output += i; | - |
285 | } executed: } Execution Count:1376 | 1376 |
286 | } executed: } Execution Count:2695 | 2695 |
287 | | - |
288 | // returns true if we performed an UTF-8 decoding | - |
289 | static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *begin, const ushort *&input, | - |
290 | const ushort *end, ushort decoded) | - |
291 | { | - |
292 | int charsNeeded; executed (the execution status of this line is deduced): int charsNeeded; | - |
293 | uint min_uc; executed (the execution status of this line is deduced): uint min_uc; | - |
294 | uint uc; executed (the execution status of this line is deduced): uint uc; | - |
295 | | - |
296 | if (decoded <= 0xC1) { evaluated: decoded <= 0xC1 yes Evaluation Count:22 | yes Evaluation Count:83 |
| 22-83 |
297 | // an UTF-8 first character must be at least 0xC0 | - |
298 | // however, all 0xC0 and 0xC1 first bytes can only produce overlong sequences | - |
299 | return false; executed: return false; Execution Count:22 | 22 |
300 | } else if (decoded < 0xe0) { evaluated: decoded < 0xe0 yes Evaluation Count:71 | yes Evaluation Count:12 |
| 12-71 |
301 | charsNeeded = 2; executed (the execution status of this line is deduced): charsNeeded = 2; | - |
302 | min_uc = 0x80; executed (the execution status of this line is deduced): min_uc = 0x80; | - |
303 | uc = decoded & 0x1f; executed (the execution status of this line is deduced): uc = decoded & 0x1f; | - |
304 | } else if (decoded < 0xf0) { executed: } Execution Count:71 evaluated: decoded < 0xf0 yes Evaluation Count:10 | yes Evaluation Count:2 |
| 2-71 |
305 | charsNeeded = 3; executed (the execution status of this line is deduced): charsNeeded = 3; | - |
306 | min_uc = 0x800; executed (the execution status of this line is deduced): min_uc = 0x800; | - |
307 | uc = decoded & 0x0f; executed (the execution status of this line is deduced): uc = decoded & 0x0f; | - |
308 | } else if (decoded < 0xf5) { executed: } Execution Count:10 partially evaluated: decoded < 0xf5 yes Evaluation Count:2 | no Evaluation Count:0 |
| 0-10 |
309 | charsNeeded = 4; executed (the execution status of this line is deduced): charsNeeded = 4; | - |
310 | min_uc = 0x10000; executed (the execution status of this line is deduced): min_uc = 0x10000; | - |
311 | uc = decoded & 0x07; executed (the execution status of this line is deduced): uc = decoded & 0x07; | - |
312 | } else { executed: } Execution Count:2 | 2 |
313 | // the last Unicode character is U+10FFFF | - |
314 | // it's encoded in UTF-8 as "\xF4\x8F\xBF\xBF" | - |
315 | // therefore, a byte higher than 0xF4 is not the UTF-8 first byte | - |
316 | return false; never executed: return false; | 0 |
317 | } | - |
318 | | - |
319 | // are there enough remaining? | - |
320 | if (end - input < 3*charsNeeded) evaluated: end - input < 3*charsNeeded yes Evaluation Count:6 | yes Evaluation Count:77 |
| 6-77 |
321 | return false; executed: return false; Execution Count:6 | 6 |
322 | | - |
323 | if (input[3] != '%') evaluated: input[3] != '%' yes Evaluation Count:1 | yes Evaluation Count:76 |
| 1-76 |
324 | return false; executed: return false; Execution Count:1 | 1 |
325 | | - |
326 | // first continuation character | - |
327 | decoded = decodePercentEncoding(input + 3); executed (the execution status of this line is deduced): decoded = decodePercentEncoding(input + 3); | - |
328 | if ((decoded & 0xc0) != 0x80) evaluated: (decoded & 0xc0) != 0x80 yes Evaluation Count:18 | yes Evaluation Count:58 |
| 18-58 |
329 | return false; executed: return false; Execution Count:18 | 18 |
330 | uc <<= 6; executed (the execution status of this line is deduced): uc <<= 6; | - |
331 | uc |= decoded & 0x3f; executed (the execution status of this line is deduced): uc |= decoded & 0x3f; | - |
332 | | - |
333 | if (charsNeeded > 2) { evaluated: charsNeeded > 2 yes Evaluation Count:5 | yes Evaluation Count:53 |
| 5-53 |
334 | if (input[6] != '%') partially evaluated: input[6] != '%' no Evaluation Count:0 | yes Evaluation Count:5 |
| 0-5 |
335 | return false; never executed: return false; | 0 |
336 | | - |
337 | // second continuation character | - |
338 | decoded = decodePercentEncoding(input + 6); executed (the execution status of this line is deduced): decoded = decodePercentEncoding(input + 6); | - |
339 | if ((decoded & 0xc0) != 0x80) partially evaluated: (decoded & 0xc0) != 0x80 no Evaluation Count:0 | yes Evaluation Count:5 |
| 0-5 |
340 | return false; never executed: return false; | 0 |
341 | uc <<= 6; executed (the execution status of this line is deduced): uc <<= 6; | - |
342 | uc |= decoded & 0x3f; executed (the execution status of this line is deduced): uc |= decoded & 0x3f; | - |
343 | | - |
344 | if (charsNeeded > 3) { evaluated: charsNeeded > 3 yes Evaluation Count:2 | yes Evaluation Count:3 |
| 2-3 |
345 | if (input[9] != '%') partially evaluated: input[9] != '%' no Evaluation Count:0 | yes Evaluation Count:2 |
| 0-2 |
346 | return false; never executed: return false; | 0 |
347 | | - |
348 | // third continuation character | - |
349 | decoded = decodePercentEncoding(input + 9); executed (the execution status of this line is deduced): decoded = decodePercentEncoding(input + 9); | - |
350 | if ((decoded & 0xc0) != 0x80) partially evaluated: (decoded & 0xc0) != 0x80 no Evaluation Count:0 | yes Evaluation Count:2 |
| 0-2 |
351 | return false; never executed: return false; | 0 |
352 | uc <<= 6; executed (the execution status of this line is deduced): uc <<= 6; | - |
353 | uc |= decoded & 0x3f; executed (the execution status of this line is deduced): uc |= decoded & 0x3f; | - |
354 | } executed: } Execution Count:2 | 2 |
355 | } executed: } Execution Count:5 | 5 |
356 | | - |
357 | // we've decoded something; safety-check it | - |
358 | if (uc < min_uc) partially evaluated: uc < min_uc no Evaluation Count:0 | yes Evaluation Count:58 |
| 0-58 |
359 | return false; never executed: return false; | 0 |
360 | if (QChar::isSurrogate(uc) || QChar::isNonCharacter(uc) || uc > QChar::LastValidCodePoint) partially evaluated: QChar::isSurrogate(uc) no Evaluation Count:0 | yes Evaluation Count:58 |
partially evaluated: QChar::isNonCharacter(uc) no Evaluation Count:0 | yes Evaluation Count:58 |
partially evaluated: uc > QChar::LastValidCodePoint no Evaluation Count:0 | yes Evaluation Count:58 |
| 0-58 |
361 | return false; never executed: return false; | 0 |
362 | | - |
363 | if (!QChar::requiresSurrogates(uc)) { evaluated: !QChar::requiresSurrogates(uc) yes Evaluation Count:56 | yes Evaluation Count:2 |
| 2-56 |
364 | // UTF-8 decoded and no surrogates are required | - |
365 | // detach if necessary | - |
366 | ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 1); executed (the execution status of this line is deduced): ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 1); | - |
367 | *output++ = uc; executed (the execution status of this line is deduced): *output++ = uc; | - |
368 | } else { executed: } Execution Count:56 | 56 |
369 | // UTF-8 decoded to something that requires a surrogate pair | - |
370 | ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 2); executed (the execution status of this line is deduced): ensureDetached(result, output, begin, input, end, -9 * charsNeeded + 2); | - |
371 | *output++ = QChar::highSurrogate(uc); executed (the execution status of this line is deduced): *output++ = QChar::highSurrogate(uc); | - |
372 | *output++ = QChar::lowSurrogate(uc); executed (the execution status of this line is deduced): *output++ = QChar::lowSurrogate(uc); | - |
373 | } executed: } Execution Count:2 | 2 |
374 | input += charsNeeded * 3 - 1; executed (the execution status of this line is deduced): input += charsNeeded * 3 - 1; | - |
375 | return true; executed: return true; Execution Count:58 | 58 |
376 | } | - |
377 | | - |
378 | static void unicodeToEncodedUtf8(QString &result, ushort *&output, const ushort *begin, | - |
379 | const ushort *&input, const ushort *end, ushort decoded) | - |
380 | { | - |
381 | uint uc = decoded; executed (the execution status of this line is deduced): uint uc = decoded; | - |
382 | if (QChar::isHighSurrogate(uc)) { evaluated: QChar::isHighSurrogate(uc) yes Evaluation Count:8 | yes Evaluation Count:70 |
| 8-70 |
383 | if (input < end && QChar::isLowSurrogate(input[1])) partially evaluated: input < end yes Evaluation Count:8 | no Evaluation Count:0 |
partially evaluated: QChar::isLowSurrogate(input[1]) yes Evaluation Count:8 | no Evaluation Count:0 |
| 0-8 |
384 | uc = QChar::surrogateToUcs4(uc, input[1]); executed: uc = QChar::surrogateToUcs4(uc, input[1]); Execution Count:8 | 8 |
385 | } executed: } Execution Count:8 | 8 |
386 | | - |
387 | // note: we will encode bad UTF-16 to UTF-8 | - |
388 | // but they don't get decoded back | - |
389 | | - |
390 | // calculate the utf8 length | - |
391 | int utf8len = uc >= 0x10000 ? 4 : uc >= 0x800 ? 3 : 2; evaluated: uc >= 0x10000 yes Evaluation Count:8 | yes Evaluation Count:70 |
| 8-70 |
392 | | - |
393 | // detach | - |
394 | if (!output) { evaluated: !output yes Evaluation Count:69 | yes Evaluation Count:9 |
| 9-69 |
395 | // we need 3 * utf8len for the encoded UTF-8 sequence | - |
396 | // but ensureDetached already adds 3 for the char we're processing | - |
397 | ensureDetached(result, output, begin, input, end, 3*utf8len - 3); executed (the execution status of this line is deduced): ensureDetached(result, output, begin, input, end, 3*utf8len - 3); | - |
398 | } else { executed: } Execution Count:69 | 69 |
399 | // verify that there's enough space or expand | - |
400 | int charsRemaining = end - input - 1; // not including this one executed (the execution status of this line is deduced): int charsRemaining = end - input - 1; | - |
401 | int pos = output - reinterpret_cast<const ushort *>(result.constData()); executed (the execution status of this line is deduced): int pos = output - reinterpret_cast<const ushort *>(result.constData()); | - |
402 | int spaceRemaining = result.size() - pos; executed (the execution status of this line is deduced): int spaceRemaining = result.size() - pos; | - |
403 | if (spaceRemaining < 3*charsRemaining + 3*utf8len) { evaluated: spaceRemaining < 3*charsRemaining + 3*utf8len yes Evaluation Count:5 | yes Evaluation Count:4 |
| 4-5 |
404 | // must resize | - |
405 | result.resize(result.size() + 3*utf8len); executed (the execution status of this line is deduced): result.resize(result.size() + 3*utf8len); | - |
406 | | - |
407 | // we know that resize() above detached, so we bypass the reference count check | - |
408 | output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData())); executed (the execution status of this line is deduced): output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData())); | - |
409 | output += pos; executed (the execution status of this line is deduced): output += pos; | - |
410 | } executed: } Execution Count:5 | 5 |
411 | } executed: } Execution Count:9 | 9 |
412 | | - |
413 | // write the sequence | - |
414 | if (uc < 0x800) { evaluated: uc < 0x800 yes Evaluation Count:61 | yes Evaluation Count:17 |
| 17-61 |
415 | // first of two bytes | - |
416 | uchar c = 0xc0 | uchar(uc >> 6); executed (the execution status of this line is deduced): uchar c = 0xc0 | uchar(uc >> 6); | - |
417 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
418 | *output++ = encodeNibble(c >> 4); executed (the execution status of this line is deduced): *output++ = encodeNibble(c >> 4); | - |
419 | *output++ = encodeNibble(c & 0xf); executed (the execution status of this line is deduced): *output++ = encodeNibble(c & 0xf); | - |
420 | } else { executed: } Execution Count:61 | 61 |
421 | uchar c; executed (the execution status of this line is deduced): uchar c; | - |
422 | if (uc > 0xFFFF) { evaluated: uc > 0xFFFF yes Evaluation Count:8 | yes Evaluation Count:9 |
| 8-9 |
423 | // first two of four bytes | - |
424 | c = 0xf0 | uchar(uc >> 18); executed (the execution status of this line is deduced): c = 0xf0 | uchar(uc >> 18); | - |
425 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
426 | *output++ = 'F'; executed (the execution status of this line is deduced): *output++ = 'F'; | - |
427 | *output++ = encodeNibble(c & 0xf); executed (the execution status of this line is deduced): *output++ = encodeNibble(c & 0xf); | - |
428 | | - |
429 | // continuation byte | - |
430 | c = 0x80 | (uchar(uc >> 12) & 0x3f); executed (the execution status of this line is deduced): c = 0x80 | (uchar(uc >> 12) & 0x3f); | - |
431 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
432 | *output++ = encodeNibble(c >> 4); executed (the execution status of this line is deduced): *output++ = encodeNibble(c >> 4); | - |
433 | *output++ = encodeNibble(c & 0xf); executed (the execution status of this line is deduced): *output++ = encodeNibble(c & 0xf); | - |
434 | | - |
435 | // this was a surrogate pair | - |
436 | ++input; executed (the execution status of this line is deduced): ++input; | - |
437 | } else { executed: } Execution Count:8 | 8 |
438 | // first of three bytes | - |
439 | c = 0xe0 | uchar(uc >> 12); executed (the execution status of this line is deduced): c = 0xe0 | uchar(uc >> 12); | - |
440 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
441 | *output++ = 'E'; executed (the execution status of this line is deduced): *output++ = 'E'; | - |
442 | *output++ = encodeNibble(c & 0xf); executed (the execution status of this line is deduced): *output++ = encodeNibble(c & 0xf); | - |
443 | } executed: } Execution Count:9 | 9 |
444 | | - |
445 | // continuation byte | - |
446 | c = 0x80 | (uchar(uc >> 6) & 0x3f); executed (the execution status of this line is deduced): c = 0x80 | (uchar(uc >> 6) & 0x3f); | - |
447 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
448 | *output++ = encodeNibble(c >> 4); executed (the execution status of this line is deduced): *output++ = encodeNibble(c >> 4); | - |
449 | *output++ = encodeNibble(c & 0xf); executed (the execution status of this line is deduced): *output++ = encodeNibble(c & 0xf); | - |
450 | } executed: } Execution Count:17 | 17 |
451 | | - |
452 | // continuation byte | - |
453 | uchar c = 0x80 | (uc & 0x3f); executed (the execution status of this line is deduced): uchar c = 0x80 | (uc & 0x3f); | - |
454 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
455 | *output++ = encodeNibble(c >> 4); executed (the execution status of this line is deduced): *output++ = encodeNibble(c >> 4); | - |
456 | *output++ = encodeNibble(c & 0xf); executed (the execution status of this line is deduced): *output++ = encodeNibble(c & 0xf); | - |
457 | } executed: } Execution Count:78 | 78 |
458 | | - |
459 | static int recode(QString &result, const ushort *begin, const ushort *end, QUrl::ComponentFormattingOptions encoding, | - |
460 | const uchar *actionTable, bool retryBadEncoding) | - |
461 | { | - |
462 | const int origSize = result.size(); executed (the execution status of this line is deduced): const int origSize = result.size(); | - |
463 | const ushort *input = begin; executed (the execution status of this line is deduced): const ushort *input = begin; | - |
464 | ushort *output = 0; executed (the execution status of this line is deduced): ushort *output = 0; | - |
465 | | - |
466 | for ( ; input != end; ++input) { evaluated: input != end yes Evaluation Count:24246 | yes Evaluation Count:7220 |
| 7220-24246 |
467 | register ushort c; executed (the execution status of this line is deduced): register ushort c; | - |
468 | EncodingAction action; executed (the execution status of this line is deduced): EncodingAction action; | - |
469 | | - |
470 | // try a run where no change is necessary | - |
471 | for ( ; input != end; ++input) { evaluated: input != end yes Evaluation Count:374852 | yes Evaluation Count:20767 |
| 20767-374852 |
472 | c = *input; executed (the execution status of this line is deduced): c = *input; | - |
473 | if (c < 0x20U) evaluated: c < 0x20U yes Evaluation Count:7 | yes Evaluation Count:374914 |
| 7-374914 |
474 | action = EncodeCharacter; executed: action = EncodeCharacter; Execution Count:7 | 7 |
475 | if (c < 0x20U || c >= 0x80U) // also: (c - 0x20 < 0x60U) evaluated: c < 0x20U yes Evaluation Count:7 | yes Evaluation Count:374761 |
evaluated: c >= 0x80U yes Evaluation Count:239 | yes Evaluation Count:374764 |
| 7-374764 |
476 | goto non_trivial; executed: goto non_trivial; Execution Count:246 | 246 |
477 | action = EncodingAction(actionTable[c - ' ']); executed (the execution status of this line is deduced): action = EncodingAction(actionTable[c - ' ']); | - |
478 | if (action == EncodeCharacter) evaluated: action == EncodeCharacter yes Evaluation Count:3321 | yes Evaluation Count:371446 |
| 3321-371446 |
479 | goto non_trivial; executed: goto non_trivial; Execution Count:3321 | 3321 |
480 | if (output) evaluated: output yes Evaluation Count:7909 | yes Evaluation Count:363482 |
| 7909-363482 |
481 | *output++ = c; executed: *output++ = c; Execution Count:7909 | 7909 |
482 | } executed: } Execution Count:371325 | 371325 |
483 | break; executed: break; Execution Count:20769 | 20769 |
484 | | - |
485 | non_trivial: | - |
486 | register uint decoded; executed (the execution status of this line is deduced): register uint decoded; | - |
487 | if (c == '%' && retryBadEncoding) { evaluated: c == '%' yes Evaluation Count:1341 | yes Evaluation Count:2226 |
evaluated: retryBadEncoding yes Evaluation Count:70 | yes Evaluation Count:1271 |
| 70-2226 |
488 | // always write "%25" | - |
489 | ensureDetached(result, output, begin, input, end); executed (the execution status of this line is deduced): ensureDetached(result, output, begin, input, end); | - |
490 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
491 | *output++ = '2'; executed (the execution status of this line is deduced): *output++ = '2'; | - |
492 | *output++ = '5'; executed (the execution status of this line is deduced): *output++ = '5'; | - |
493 | continue; executed: continue; Execution Count:70 | 70 |
494 | } else if (c == '%') { evaluated: c == '%' yes Evaluation Count:1271 | yes Evaluation Count:2226 |
| 1271-2226 |
495 | // check if the input is valid | - |
496 | if (input + 2 >= end || (decoded = decodePercentEncoding(input)) == ushort(-1)) { evaluated: input + 2 >= end yes Evaluation Count:23 | yes Evaluation Count:1248 |
evaluated: (decoded = decodePercentEncoding(input)) == ushort(-1) yes Evaluation Count:40 | yes Evaluation Count:1208 |
| 23-1248 |
497 | // not valid, retry | - |
498 | result.resize(origSize); executed (the execution status of this line is deduced): result.resize(origSize); | - |
499 | return recode(result, begin, end, encoding, actionTable, true); executed: return recode(result, begin, end, encoding, actionTable, true); Execution Count:63 | 63 |
500 | } | - |
501 | | - |
502 | if (decoded >= 0x80) { evaluated: decoded >= 0x80 yes Evaluation Count:126 | yes Evaluation Count:1082 |
| 126-1082 |
503 | // decode the UTF-8 sequence | - |
504 | if (!(encoding & QUrl::EncodeUnicode) && evaluated: !(encoding & QUrl::EncodeUnicode) yes Evaluation Count:105 | yes Evaluation Count:21 |
| 21-105 |
505 | encodedUtf8ToUtf16(result, output, begin, input, end, decoded)) evaluated: encodedUtf8ToUtf16(result, output, begin, input, end, decoded) yes Evaluation Count:58 | yes Evaluation Count:47 |
| 47-58 |
506 | continue; executed: continue; Execution Count:58 | 58 |
507 | | - |
508 | // decoding the encoded UTF-8 failed | - |
509 | action = LeaveCharacter; executed (the execution status of this line is deduced): action = LeaveCharacter; | - |
510 | } else if (decoded >= 0x20) { executed: } Execution Count:68 evaluated: decoded >= 0x20 yes Evaluation Count:935 | yes Evaluation Count:147 |
| 68-935 |
511 | action = EncodingAction(actionTable[decoded - ' ']); executed (the execution status of this line is deduced): action = EncodingAction(actionTable[decoded - ' ']); | - |
512 | } executed: } Execution Count:935 | 935 |
513 | } else { | - |
514 | decoded = c; executed (the execution status of this line is deduced): decoded = c; | - |
515 | if (decoded >= 0x80 && encoding & QUrl::EncodeUnicode) { evaluated: decoded >= 0x80 yes Evaluation Count:239 | yes Evaluation Count:1987 |
evaluated: encoding & QUrl::EncodeUnicode yes Evaluation Count:78 | yes Evaluation Count:161 |
| 78-1987 |
516 | // encode the UTF-8 sequence | - |
517 | unicodeToEncodedUtf8(result, output, begin, input, end, decoded); executed (the execution status of this line is deduced): unicodeToEncodedUtf8(result, output, begin, input, end, decoded); | - |
518 | continue; executed: continue; Execution Count:78 | 78 |
519 | } else if (decoded >= 0x80) { evaluated: decoded >= 0x80 yes Evaluation Count:161 | yes Evaluation Count:1987 |
| 161-1987 |
520 | if (output) partially evaluated: output no Evaluation Count:0 | yes Evaluation Count:161 |
| 0-161 |
521 | *output++ = c; never executed: *output++ = c; | 0 |
522 | continue; executed: continue; Execution Count:161 | 161 |
523 | } | - |
524 | } | - |
525 | | - |
526 | // there are six possibilities: | - |
527 | // current \ action | DecodeCharacter | LeaveCharacter | EncodeCharacter | - |
528 | // decoded | 1:leave | 2:leave | 3:encode | - |
529 | // encoded | 4:decode | 5:leave | 6:leave | - |
530 | // cases 1 and 2 were handled before this section | - |
531 | | - |
532 | if (c == '%' && action != DecodeCharacter) { evaluated: c == '%' yes Evaluation Count:1150 | yes Evaluation Count:1987 |
evaluated: action != DecodeCharacter yes Evaluation Count:759 | yes Evaluation Count:391 |
| 391-1987 |
533 | // cases 5 and 6: it's encoded and we're leaving it as it is | - |
534 | // except we're pedantic and we'll uppercase the hex | - |
535 | if (output || !isUpperHex(input[1]) || !isUpperHex(input[2])) { evaluated: output yes Evaluation Count:95 | yes Evaluation Count:664 |
evaluated: !isUpperHex(input[1]) yes Evaluation Count:5 | yes Evaluation Count:659 |
evaluated: !isUpperHex(input[2]) yes Evaluation Count:20 | yes Evaluation Count:639 |
| 5-664 |
536 | ensureDetached(result, output, begin, input, end); executed (the execution status of this line is deduced): ensureDetached(result, output, begin, input, end); | - |
537 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
538 | *output++ = toUpperHex(*++input); executed (the execution status of this line is deduced): *output++ = toUpperHex(*++input); | - |
539 | *output++ = toUpperHex(*++input); executed (the execution status of this line is deduced): *output++ = toUpperHex(*++input); | - |
540 | } executed: } Execution Count:120 | 120 |
541 | } else if (c == '%' && action == DecodeCharacter) { executed: } Execution Count:759 evaluated: c == '%' yes Evaluation Count:391 | yes Evaluation Count:1987 |
partially evaluated: action == DecodeCharacter yes Evaluation Count:391 | no Evaluation Count:0 |
| 0-1987 |
542 | // case 4: we need to decode | - |
543 | ensureDetached(result, output, begin, input, end); executed (the execution status of this line is deduced): ensureDetached(result, output, begin, input, end); | - |
544 | *output++ = decoded; executed (the execution status of this line is deduced): *output++ = decoded; | - |
545 | input += 2; executed (the execution status of this line is deduced): input += 2; | - |
546 | } else { executed: } Execution Count:391 | 391 |
547 | // must be case 3: we need to encode | - |
548 | ensureDetached(result, output, begin, input, end); executed (the execution status of this line is deduced): ensureDetached(result, output, begin, input, end); | - |
549 | *output++ = '%'; executed (the execution status of this line is deduced): *output++ = '%'; | - |
550 | *output++ = encodeNibble(c >> 4); executed (the execution status of this line is deduced): *output++ = encodeNibble(c >> 4); | - |
551 | *output++ = encodeNibble(c & 0xf); executed (the execution status of this line is deduced): *output++ = encodeNibble(c & 0xf); | - |
552 | } executed: } Execution Count:1987 | 1987 |
553 | } | - |
554 | | - |
555 | if (output) { evaluated: output yes Evaluation Count:1375 | yes Evaluation Count:26578 |
| 1375-26578 |
556 | int len = output - reinterpret_cast<const ushort *>(result.constData()); executed (the execution status of this line is deduced): int len = output - reinterpret_cast<const ushort *>(result.constData()); | - |
557 | result.truncate(len); executed (the execution status of this line is deduced): result.truncate(len); | - |
558 | return len - origSize; executed: return len - origSize; Execution Count:1375 | 1375 |
559 | } | - |
560 | return 0; executed: return 0; Execution Count:26575 | 26575 |
561 | } | - |
562 | | - |
563 | static int decode(QString &appendTo, const ushort *begin, const ushort *end) | - |
564 | { | - |
565 | const int origSize = appendTo.size(); executed (the execution status of this line is deduced): const int origSize = appendTo.size(); | - |
566 | const ushort *input = begin; executed (the execution status of this line is deduced): const ushort *input = begin; | - |
567 | ushort *output = 0; executed (the execution status of this line is deduced): ushort *output = 0; | - |
568 | while (input != end) { evaluated: input != end yes Evaluation Count:351310 | yes Evaluation Count:6322 |
| 6322-351310 |
569 | if (*input != '%') { evaluated: *input != '%' yes Evaluation Count:351297 | yes Evaluation Count:13 |
| 13-351297 |
570 | if (output) evaluated: output yes Evaluation Count:38 | yes Evaluation Count:351259 |
| 38-351259 |
571 | *output++ = *input; executed: *output++ = *input; Execution Count:38 | 38 |
572 | ++input; executed (the execution status of this line is deduced): ++input; | - |
573 | continue; executed: continue; Execution Count:351297 | 351297 |
574 | } | - |
575 | | - |
576 | if (Q_UNLIKELY(!output)) { evaluated: __builtin_expect(!!(!output), false) yes Evaluation Count:11 | yes Evaluation Count:2 |
| 2-11 |
577 | // detach | - |
578 | appendTo.resize(origSize + (end - begin)); executed (the execution status of this line is deduced): appendTo.resize(origSize + (end - begin)); | - |
579 | output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize; executed (the execution status of this line is deduced): output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize; | - |
580 | memcpy(output, begin, (input - begin) * sizeof(ushort)); executed (the execution status of this line is deduced): memcpy(output, begin, (input - begin) * sizeof(ushort)); | - |
581 | output += input - begin; executed (the execution status of this line is deduced): output += input - begin; | - |
582 | } executed: } Execution Count:11 | 11 |
583 | | - |
584 | ++input; executed (the execution status of this line is deduced): ++input; | - |
585 | Q_ASSERT(input <= end - 2); // we need two characters executed (the execution status of this line is deduced): qt_noop(); | - |
586 | Q_ASSERT(isHex(input[0])); executed (the execution status of this line is deduced): qt_noop(); | - |
587 | Q_ASSERT(isHex(input[1])); executed (the execution status of this line is deduced): qt_noop(); | - |
588 | *output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]); executed (the execution status of this line is deduced): *output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]); | - |
589 | input += 2; executed (the execution status of this line is deduced): input += 2; | - |
590 | } executed: } Execution Count:13 | 13 |
591 | | - |
592 | if (output) { evaluated: output yes Evaluation Count:11 | yes Evaluation Count:6311 |
| 11-6311 |
593 | int len = output - reinterpret_cast<ushort *>(appendTo.begin()); executed (the execution status of this line is deduced): int len = output - reinterpret_cast<ushort *>(appendTo.begin()); | - |
594 | appendTo.truncate(len); executed (the execution status of this line is deduced): appendTo.truncate(len); | - |
595 | return len - origSize; executed: return len - origSize; Execution Count:11 | 11 |
596 | } | - |
597 | return 0; executed: return 0; Execution Count:6311 | 6311 |
598 | } | - |
599 | | - |
600 | template <size_t N> | - |
601 | static void maskTable(uchar (&table)[N], const uchar (&mask)[N]) | - |
602 | { | - |
603 | for (size_t i = 0; i < N; ++i) evaluated: i < N yes Evaluation Count:170213 | yes Evaluation Count:1785 |
| 1785-170213 |
604 | table[i] &= mask[i]; executed: table[i] &= mask[i]; Execution Count:170115 | 170115 |
605 | } executed: } Execution Count:1785 | 1785 |
606 | | - |
607 | /*! | - |
608 | \internal | - |
609 | | - |
610 | Recodes the string from \a begin to \a end. If any transformations are | - |
611 | done, append them to \a appendTo and return the number of characters added. | - |
612 | If no transformations were required, return 0. | - |
613 | | - |
614 | The \a encoding option modifies the default behaviour: | - |
615 | \list | - |
616 | \li QUrl::EncodeDelimiters: if set, delimiters will be left untransformed (note: not encoded!); | - |
617 | if unset, delimiters will be decoded | - |
618 | \li QUrl::DecodeReserved: if set, reserved characters will be decoded; | - |
619 | if unset, reserved characters will be encoded | - |
620 | \li QUrl::EncodeSpaces: if set, spaces will be encoded to "%20"; if unset, they will be " " | - |
621 | \li QUrl::EncodeUnicode: if set, characters above U+0080 will be encoded to their UTF-8 | - |
622 | percent-encoded form; if unset, they will be decoded to UTF-16 | - |
623 | \li QUrl::FullyDecoded: if set, this function will decode all percent-encoded sequences, | - |
624 | including that of the percent character. The resulting string | - |
625 | will not be percent-encoded anymore. Use with caution! | - |
626 | In this mode, the behaviour is undefined if the input string | - |
627 | contains any percent-encoding sequences above %80. | - |
628 | Also, the function will not correct bad % sequences. | - |
629 | \endlist | - |
630 | | - |
631 | Other flags are ignored (including QUrl::EncodeReserved). | - |
632 | | - |
633 | The \a tableModifications argument can be used to supply extra | - |
634 | modifications to the tables, to be applied after the flags above are | - |
635 | handled. It consists of a sequence of 16-bit values, where the low 8 bits | - |
636 | indicate the character in question and the high 8 bits are either \c | - |
637 | EncodeCharacter, \c LeaveCharacter or \c DecodeCharacter. | - |
638 | */ | - |
639 | | - |
640 | Q_AUTOTEST_EXPORT int | - |
641 | qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end, | - |
642 | QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications) | - |
643 | { | - |
644 | uchar actionTable[sizeof defaultActionTable]; executed (the execution status of this line is deduced): uchar actionTable[sizeof defaultActionTable]; | - |
645 | if (encoding == QUrl::FullyDecoded) { evaluated: encoding == QUrl::FullyDecoded yes Evaluation Count:6322 | yes Evaluation Count:27896 |
| 6322-27896 |
646 | return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end)); executed: return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end)); Execution Count:6322 | 6322 |
647 | } | - |
648 | | - |
649 | if (!(encoding & QUrl::EncodeDelimiters) && encoding & QUrl::DecodeReserved) { evaluated: !(encoding & QUrl::EncodeDelimiters) yes Evaluation Count:22260 | yes Evaluation Count:5633 |
evaluated: encoding & QUrl::DecodeReserved yes Evaluation Count:20544 | yes Evaluation Count:1753 |
| 1753-22260 |
650 | // reset the table | - |
651 | memset(actionTable, DecodeCharacter, sizeof actionTable); executed (the execution status of this line is deduced): memset(actionTable, DecodeCharacter, sizeof actionTable); | - |
652 | if (encoding & QUrl::EncodeSpaces) evaluated: encoding & QUrl::EncodeSpaces yes Evaluation Count:8 | yes Evaluation Count:20504 |
| 8-20504 |
653 | actionTable[0] = EncodeCharacter; executed: actionTable[0] = EncodeCharacter; Execution Count:8 | 8 |
654 | | - |
655 | // these are always encoded | - |
656 | actionTable['%' - ' '] = EncodeCharacter; executed (the execution status of this line is deduced): actionTable['%' - ' '] = EncodeCharacter; | - |
657 | actionTable[0x7F - ' '] = EncodeCharacter; executed (the execution status of this line is deduced): actionTable[0x7F - ' '] = EncodeCharacter; | - |
658 | } else { executed: } Execution Count:20499 | 20499 |
659 | memcpy(actionTable, defaultActionTable, sizeof actionTable); executed (the execution status of this line is deduced): memcpy(actionTable, defaultActionTable, sizeof actionTable); | - |
660 | if (!(encoding & QUrl::EncodeDelimiters)) evaluated: !(encoding & QUrl::EncodeDelimiters) yes Evaluation Count:1747 | yes Evaluation Count:5633 |
| 1747-5633 |
661 | maskTable(actionTable, delimsMask); executed: maskTable(actionTable, delimsMask); Execution Count:1747 | 1747 |
662 | if (encoding & QUrl::DecodeReserved) evaluated: encoding & QUrl::DecodeReserved yes Evaluation Count:26 | yes Evaluation Count:7365 |
| 26-7365 |
663 | maskTable(actionTable, reservedMask); executed: maskTable(actionTable, reservedMask); Execution Count:26 | 26 |
664 | if (!(encoding & QUrl::EncodeSpaces)) evaluated: !(encoding & QUrl::EncodeSpaces) yes Evaluation Count:2229 | yes Evaluation Count:5162 |
| 2229-5162 |
665 | actionTable[0] = DecodeCharacter; // decode executed: actionTable[0] = DecodeCharacter; Execution Count:2229 | 2229 |
666 | } executed: } Execution Count:7391 | 7391 |
667 | | - |
668 | if (tableModifications) { evaluated: tableModifications yes Evaluation Count:17787 | yes Evaluation Count:10161 |
| 10161-17787 |
669 | for (const ushort *p = tableModifications; *p; ++p) evaluated: *p yes Evaluation Count:50028 | yes Evaluation Count:17796 |
| 17796-50028 |
670 | actionTable[uchar(*p) - ' '] = *p >> 8; executed: actionTable[uchar(*p) - ' '] = *p >> 8; Execution Count:50020 | 50020 |
671 | } executed: } Execution Count:17802 | 17802 |
672 | | - |
673 | return recode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end), executed: return recode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end), encoding, actionTable, false); Execution Count:27940 | 27940 |
674 | encoding, actionTable, false); executed: return recode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end), encoding, actionTable, false); Execution Count:27940 | 27940 |
675 | } | - |
676 | | - |
677 | /*! | - |
678 | \internal | - |
679 | \since 5.0 | - |
680 | | - |
681 | \a ba contains an 8-bit form of the component and it might be | - |
682 | percent-encoded already. We can't use QString::fromUtf8 because it might | - |
683 | contain non-UTF8 sequences. We can't use QByteArray::toPercentEncoding | - |
684 | because it might already contain percent-encoded sequences. We can't use | - |
685 | qt_urlRecode because it needs UTF-16 input. | - |
686 | */ | - |
687 | Q_AUTOTEST_EXPORT | - |
688 | QString qt_urlRecodeByteArray(const QByteArray &ba) | - |
689 | { | - |
690 | if (ba.isNull()) evaluated: ba.isNull() yes Evaluation Count:2 | yes Evaluation Count:35 |
| 2-35 |
691 | return QString(); executed: return QString(); Execution Count:2 | 2 |
692 | | - |
693 | // scan ba for anything above or equal to 0x80 | - |
694 | // control points below 0x20 are fine in QString | - |
695 | const char *in = ba.constData(); executed (the execution status of this line is deduced): const char *in = ba.constData(); | - |
696 | const char *const end = ba.constEnd(); executed (the execution status of this line is deduced): const char *const end = ba.constEnd(); | - |
697 | for ( ; in < end; ++in) { evaluated: in < end yes Evaluation Count:565 | yes Evaluation Count:33 |
| 33-565 |
698 | if (*in & 0x80) evaluated: *in & 0x80 yes Evaluation Count:2 | yes Evaluation Count:563 |
| 2-563 |
699 | break; executed: break; Execution Count:2 | 2 |
700 | } executed: } Execution Count:563 | 563 |
701 | | - |
702 | if (in == end) { evaluated: in == end yes Evaluation Count:33 | yes Evaluation Count:2 |
| 2-33 |
703 | // no non-ASCII found, we're safe to convert to QString | - |
704 | return QString::fromLatin1(ba, ba.size()); executed: return QString::fromLatin1(ba, ba.size()); Execution Count:33 | 33 |
705 | } | - |
706 | | - |
707 | // we found something that we need to encode | - |
708 | QByteArray intermediate = ba; executed (the execution status of this line is deduced): QByteArray intermediate = ba; | - |
709 | intermediate.resize(ba.size() * 3 - (in - ba.constData())); executed (the execution status of this line is deduced): intermediate.resize(ba.size() * 3 - (in - ba.constData())); | - |
710 | uchar *out = reinterpret_cast<uchar *>(intermediate.data() + (in - ba.constData())); executed (the execution status of this line is deduced): uchar *out = reinterpret_cast<uchar *>(intermediate.data() + (in - ba.constData())); | - |
711 | for ( ; in < end; ++in) { evaluated: in < end yes Evaluation Count:4 | yes Evaluation Count:2 |
| 2-4 |
712 | if (*in & 0x80) { partially evaluated: *in & 0x80 yes Evaluation Count:4 | no Evaluation Count:0 |
| 0-4 |
713 | // encode | - |
714 | *out++ = '%'; executed (the execution status of this line is deduced): *out++ = '%'; | - |
715 | *out++ = encodeNibble(uchar(*in) >> 4); executed (the execution status of this line is deduced): *out++ = encodeNibble(uchar(*in) >> 4); | - |
716 | *out++ = encodeNibble(uchar(*in) & 0xf); executed (the execution status of this line is deduced): *out++ = encodeNibble(uchar(*in) & 0xf); | - |
717 | } else { executed: } Execution Count:4 | 4 |
718 | // keep | - |
719 | *out++ = uchar(*in); never executed (the execution status of this line is deduced): *out++ = uchar(*in); | - |
720 | } | 0 |
721 | } | - |
722 | | - |
723 | // now it's safe to call fromLatin1 | - |
724 | return QString::fromLatin1(intermediate, out - reinterpret_cast<uchar *>(intermediate.data())); executed: return QString::fromLatin1(intermediate, out - reinterpret_cast<uchar *>(intermediate.data())); Execution Count:2 | 2 |
725 | } | - |
726 | | - |
727 | QT_END_NAMESPACE | - |
728 | | - |
| | |