| Absolute File Name: | /home/qt/qt5_coco/qt5/qtbase/src/corelib/io/qurlrecode.cpp |
| Source code | Switch to Preprocessed file |
| Line | Source | Count | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | /**************************************************************************** | - | ||||||||||||||||||
| 2 | ** | - | ||||||||||||||||||
| 3 | ** Copyright (C) 2012 Intel Corporation | - | ||||||||||||||||||
| 4 | ** Contact: http://www.qt.io/licensing/ | - | ||||||||||||||||||
| 5 | ** | - | ||||||||||||||||||
| 6 | ** This file is part of the QtCore module of the Qt Toolkit. | - | ||||||||||||||||||
| 7 | ** | - | ||||||||||||||||||
| 8 | ** $QT_BEGIN_LICENSE:LGPL21$ | - | ||||||||||||||||||
| 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 The Qt Company. For licensing terms | - | ||||||||||||||||||
| 14 | ** and conditions see http://www.qt.io/terms-conditions. For further | - | ||||||||||||||||||
| 15 | ** information use the contact form at http://www.qt.io/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 or version 3 as published by the Free | - | ||||||||||||||||||
| 20 | ** Software Foundation and appearing in the file LICENSE.LGPLv21 and | - | ||||||||||||||||||
| 21 | ** LICENSE.LGPLv3 included in the packaging of this file. Please review the | - | ||||||||||||||||||
| 22 | ** following information to ensure the GNU Lesser General Public License | - | ||||||||||||||||||
| 23 | ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and | - | ||||||||||||||||||
| 24 | ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. | - | ||||||||||||||||||
| 25 | ** | - | ||||||||||||||||||
| 26 | ** As a special exception, The Qt Company gives you certain additional | - | ||||||||||||||||||
| 27 | ** rights. These rights are described in The Qt Company LGPL Exception | - | ||||||||||||||||||
| 28 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. | - | ||||||||||||||||||
| 29 | ** | - | ||||||||||||||||||
| 30 | ** $QT_END_LICENSE$ | - | ||||||||||||||||||
| 31 | ** | - | ||||||||||||||||||
| 32 | ****************************************************************************/ | - | ||||||||||||||||||
| 33 | - | |||||||||||||||||||
| 34 | #include "qurl.h" | - | ||||||||||||||||||
| 35 | #include "private/qutfcodec_p.h" | - | ||||||||||||||||||
| 36 | #include "private/qtools_p.h" | - | ||||||||||||||||||
| 37 | - | |||||||||||||||||||
| 38 | QT_BEGIN_NAMESPACE | - | ||||||||||||||||||
| 39 | - | |||||||||||||||||||
| 40 | // ### move to qurl_p.h | - | ||||||||||||||||||
| 41 | enum EncodingAction { | - | ||||||||||||||||||
| 42 | DecodeCharacter = 0, | - | ||||||||||||||||||
| 43 | LeaveCharacter = 1, | - | ||||||||||||||||||
| 44 | EncodeCharacter = 2 | - | ||||||||||||||||||
| 45 | }; | - | ||||||||||||||||||
| 46 | - | |||||||||||||||||||
| 47 | // From RFC 3896, Appendix A Collected ABNF for URI | - | ||||||||||||||||||
| 48 | // unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" | - | ||||||||||||||||||
| 49 | // reserved = gen-delims / sub-delims | - | ||||||||||||||||||
| 50 | // gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" | - | ||||||||||||||||||
| 51 | // sub-delims = "!" / "$" / "&" / "'" / "(" / ")" | - | ||||||||||||||||||
| 52 | // / "*" / "+" / "," / ";" / "=" | - | ||||||||||||||||||
| 53 | static const uchar defaultActionTable[96] = { | - | ||||||||||||||||||
| 54 | 2, // space | - | ||||||||||||||||||
| 55 | 1, // '!' (sub-delim) | - | ||||||||||||||||||
| 56 | 2, // '"' | - | ||||||||||||||||||
| 57 | 1, // '#' (gen-delim) | - | ||||||||||||||||||
| 58 | 1, // '$' (gen-delim) | - | ||||||||||||||||||
| 59 | 2, // '%' (percent) | - | ||||||||||||||||||
| 60 | 1, // '&' (gen-delim) | - | ||||||||||||||||||
| 61 | 1, // "'" (sub-delim) | - | ||||||||||||||||||
| 62 | 1, // '(' (sub-delim) | - | ||||||||||||||||||
| 63 | 1, // ')' (sub-delim) | - | ||||||||||||||||||
| 64 | 1, // '*' (sub-delim) | - | ||||||||||||||||||
| 65 | 1, // '+' (sub-delim) | - | ||||||||||||||||||
| 66 | 1, // ',' (sub-delim) | - | ||||||||||||||||||
| 67 | 0, // '-' (unreserved) | - | ||||||||||||||||||
| 68 | 0, // '.' (unreserved) | - | ||||||||||||||||||
| 69 | 1, // '/' (gen-delim) | - | ||||||||||||||||||
| 70 | - | |||||||||||||||||||
| 71 | 0, 0, 0, 0, 0, // '0' to '4' (unreserved) | - | ||||||||||||||||||
| 72 | 0, 0, 0, 0, 0, // '5' to '9' (unreserved) | - | ||||||||||||||||||
| 73 | 1, // ':' (gen-delim) | - | ||||||||||||||||||
| 74 | 1, // ';' (sub-delim) | - | ||||||||||||||||||
| 75 | 2, // '<' | - | ||||||||||||||||||
| 76 | 1, // '=' (sub-delim) | - | ||||||||||||||||||
| 77 | 2, // '>' | - | ||||||||||||||||||
| 78 | 1, // '?' (gen-delim) | - | ||||||||||||||||||
| 79 | - | |||||||||||||||||||
| 80 | 1, // '@' (gen-delim) | - | ||||||||||||||||||
| 81 | 0, 0, 0, 0, 0, // 'A' to 'E' (unreserved) | - | ||||||||||||||||||
| 82 | 0, 0, 0, 0, 0, // 'F' to 'J' (unreserved) | - | ||||||||||||||||||
| 83 | 0, 0, 0, 0, 0, // 'K' to 'O' (unreserved) | - | ||||||||||||||||||
| 84 | 0, 0, 0, 0, 0, // 'P' to 'T' (unreserved) | - | ||||||||||||||||||
| 85 | 0, 0, 0, 0, 0, 0, // 'U' to 'Z' (unreserved) | - | ||||||||||||||||||
| 86 | 1, // '[' (gen-delim) | - | ||||||||||||||||||
| 87 | 2, // '\' | - | ||||||||||||||||||
| 88 | 1, // ']' (gen-delim) | - | ||||||||||||||||||
| 89 | 2, // '^' | - | ||||||||||||||||||
| 90 | 0, // '_' (unreserved) | - | ||||||||||||||||||
| 91 | - | |||||||||||||||||||
| 92 | 2, // '`' | - | ||||||||||||||||||
| 93 | 0, 0, 0, 0, 0, // 'a' to 'e' (unreserved) | - | ||||||||||||||||||
| 94 | 0, 0, 0, 0, 0, // 'f' to 'j' (unreserved) | - | ||||||||||||||||||
| 95 | 0, 0, 0, 0, 0, // 'k' to 'o' (unreserved) | - | ||||||||||||||||||
| 96 | 0, 0, 0, 0, 0, // 'p' to 't' (unreserved) | - | ||||||||||||||||||
| 97 | 0, 0, 0, 0, 0, 0, // 'u' to 'z' (unreserved) | - | ||||||||||||||||||
| 98 | 2, // '{' | - | ||||||||||||||||||
| 99 | 2, // '|' | - | ||||||||||||||||||
| 100 | 2, // '}' | - | ||||||||||||||||||
| 101 | 0, // '~' (unreserved) | - | ||||||||||||||||||
| 102 | - | |||||||||||||||||||
| 103 | 2 // BSKP | - | ||||||||||||||||||
| 104 | }; | - | ||||||||||||||||||
| 105 | - | |||||||||||||||||||
| 106 | // mask tables, in negative polarity | - | ||||||||||||||||||
| 107 | // 0x00 if it belongs to this category | - | ||||||||||||||||||
| 108 | // 0xff if it doesn't | - | ||||||||||||||||||
| 109 | - | |||||||||||||||||||
| 110 | static const uchar reservedMask[96] = { | - | ||||||||||||||||||
| 111 | 0xff, // space | - | ||||||||||||||||||
| 112 | 0xff, // '!' (sub-delim) | - | ||||||||||||||||||
| 113 | 0x00, // '"' | - | ||||||||||||||||||
| 114 | 0xff, // '#' (gen-delim) | - | ||||||||||||||||||
| 115 | 0xff, // '$' (gen-delim) | - | ||||||||||||||||||
| 116 | 0xff, // '%' (percent) | - | ||||||||||||||||||
| 117 | 0xff, // '&' (gen-delim) | - | ||||||||||||||||||
| 118 | 0xff, // "'" (sub-delim) | - | ||||||||||||||||||
| 119 | 0xff, // '(' (sub-delim) | - | ||||||||||||||||||
| 120 | 0xff, // ')' (sub-delim) | - | ||||||||||||||||||
| 121 | 0xff, // '*' (sub-delim) | - | ||||||||||||||||||
| 122 | 0xff, // '+' (sub-delim) | - | ||||||||||||||||||
| 123 | 0xff, // ',' (sub-delim) | - | ||||||||||||||||||
| 124 | 0xff, // '-' (unreserved) | - | ||||||||||||||||||
| 125 | 0xff, // '.' (unreserved) | - | ||||||||||||||||||
| 126 | 0xff, // '/' (gen-delim) | - | ||||||||||||||||||
| 127 | - | |||||||||||||||||||
| 128 | 0xff, 0xff, 0xff, 0xff, 0xff, // '0' to '4' (unreserved) | - | ||||||||||||||||||
| 129 | 0xff, 0xff, 0xff, 0xff, 0xff, // '5' to '9' (unreserved) | - | ||||||||||||||||||
| 130 | 0xff, // ':' (gen-delim) | - | ||||||||||||||||||
| 131 | 0xff, // ';' (sub-delim) | - | ||||||||||||||||||
| 132 | 0x00, // '<' | - | ||||||||||||||||||
| 133 | 0xff, // '=' (sub-delim) | - | ||||||||||||||||||
| 134 | 0x00, // '>' | - | ||||||||||||||||||
| 135 | 0xff, // '?' (gen-delim) | - | ||||||||||||||||||
| 136 | - | |||||||||||||||||||
| 137 | 0xff, // '@' (gen-delim) | - | ||||||||||||||||||
| 138 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'A' to 'E' (unreserved) | - | ||||||||||||||||||
| 139 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'F' to 'J' (unreserved) | - | ||||||||||||||||||
| 140 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'K' to 'O' (unreserved) | - | ||||||||||||||||||
| 141 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'P' to 'T' (unreserved) | - | ||||||||||||||||||
| 142 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'U' to 'Z' (unreserved) | - | ||||||||||||||||||
| 143 | 0xff, // '[' (gen-delim) | - | ||||||||||||||||||
| 144 | 0x00, // '\' | - | ||||||||||||||||||
| 145 | 0xff, // ']' (gen-delim) | - | ||||||||||||||||||
| 146 | 0x00, // '^' | - | ||||||||||||||||||
| 147 | 0xff, // '_' (unreserved) | - | ||||||||||||||||||
| 148 | - | |||||||||||||||||||
| 149 | 0x00, // '`' | - | ||||||||||||||||||
| 150 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'a' to 'e' (unreserved) | - | ||||||||||||||||||
| 151 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'f' to 'j' (unreserved) | - | ||||||||||||||||||
| 152 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'k' to 'o' (unreserved) | - | ||||||||||||||||||
| 153 | 0xff, 0xff, 0xff, 0xff, 0xff, // 'p' to 't' (unreserved) | - | ||||||||||||||||||
| 154 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // 'u' to 'z' (unreserved) | - | ||||||||||||||||||
| 155 | 0x00, // '{' | - | ||||||||||||||||||
| 156 | 0x00, // '|' | - | ||||||||||||||||||
| 157 | 0x00, // '}' | - | ||||||||||||||||||
| 158 | 0xff, // '~' (unreserved) | - | ||||||||||||||||||
| 159 | - | |||||||||||||||||||
| 160 | 0xff // BSKP | - | ||||||||||||||||||
| 161 | }; | - | ||||||||||||||||||
| 162 | - | |||||||||||||||||||
| 163 | static inline bool isHex(ushort c) | - | ||||||||||||||||||
| 164 | { | - | ||||||||||||||||||
| 165 | return (c >= 'a' && c <= 'f') || executed 5213 times by 10 tests: return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9');Executed by:
| 29-5213 | ||||||||||||||||||
| 166 | (c >= 'A' && c <= 'F') || executed 5213 times by 10 tests: return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9');Executed by:
| 29-5213 | ||||||||||||||||||
| 167 | (c >= '0' && c <= '9'); executed 5213 times by 10 tests: return (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F') || (c >= '0' && c <= '9');Executed by:
| 11-5213 | ||||||||||||||||||
| 168 | } | - | ||||||||||||||||||
| 169 | - | |||||||||||||||||||
| 170 | static inline bool isUpperHex(ushort c) | - | ||||||||||||||||||
| 171 | { | - | ||||||||||||||||||
| 172 | // undefined behaviour if c isn't an hex char! | - | ||||||||||||||||||
| 173 | return c < 0x60; executed 3707 times by 6 tests: return c < 0x60;Executed by:
| 3707 | ||||||||||||||||||
| 174 | } | - | ||||||||||||||||||
| 175 | - | |||||||||||||||||||
| 176 | static inline ushort toUpperHex(ushort c) | - | ||||||||||||||||||
| 177 | { | - | ||||||||||||||||||
| 178 | return isUpperHex(c) ? c : c - 0x20; executed 248 times by 4 tests: return isUpperHex(c) ? c : c - 0x20;Executed by:
| 51-248 | ||||||||||||||||||
| 179 | } | - | ||||||||||||||||||
| 180 | - | |||||||||||||||||||
| 181 | static inline ushort decodeNibble(ushort c) | - | ||||||||||||||||||
| 182 | { | - | ||||||||||||||||||
| 183 | return c >= 'a' ? c - 'a' + 0xA : executed 5146 times by 10 tests: return c >= 'a' ? c - 'a' + 0xA : c >= 'A' ? c - 'A' + 0xA : c - '0';Executed by:
| 109-5146 | ||||||||||||||||||
| 184 | c >= 'A' ? c - 'A' + 0xA : c - '0'; executed 5146 times by 10 tests: return c >= 'a' ? c - 'a' + 0xA : c >= 'A' ? c - 'A' + 0xA : c - '0';Executed by:
| 1537-5146 | ||||||||||||||||||
| 185 | } | - | ||||||||||||||||||
| 186 | - | |||||||||||||||||||
| 187 | // if the sequence at input is 2*HEXDIG, returns its decoding | - | ||||||||||||||||||
| 188 | // returns -1 if it isn't. | - | ||||||||||||||||||
| 189 | // assumes that the range has been checked already | - | ||||||||||||||||||
| 190 | static inline ushort decodePercentEncoding(const ushort *input) | - | ||||||||||||||||||
| 191 | { | - | ||||||||||||||||||
| 192 | ushort c1 = input[1]; | - | ||||||||||||||||||
| 193 | ushort c2 = input[2]; | - | ||||||||||||||||||
| 194 | if (!isHex(c1) || !isHex(c2))
| 13-2509 | ||||||||||||||||||
| 195 | return ushort(-1); executed 33 times by 3 tests: return ushort(-1);Executed by:
| 33 | ||||||||||||||||||
| 196 | return decodeNibble(c1) << 4 | decodeNibble(c2); executed 2489 times by 10 tests: return decodeNibble(c1) << 4 | decodeNibble(c2);Executed by:
| 2489 | ||||||||||||||||||
| 197 | } | - | ||||||||||||||||||
| 198 | - | |||||||||||||||||||
| 199 | static inline ushort encodeNibble(ushort c) | - | ||||||||||||||||||
| 200 | { | - | ||||||||||||||||||
| 201 | return ushort(QtMiscUtils::toHexUpper(c)); executed 4470 times by 9 tests: return ushort(QtMiscUtils::toHexUpper(c));Executed by:
| 4470 | ||||||||||||||||||
| 202 | } | - | ||||||||||||||||||
| 203 | - | |||||||||||||||||||
| 204 | static void ensureDetached(QString &result, ushort *&output, const ushort *begin, const ushort *input, const ushort *end, | - | ||||||||||||||||||
| 205 | int add = 0) | - | ||||||||||||||||||
| 206 | { | - | ||||||||||||||||||
| 207 | if (!output) {
| 1322-1454 | ||||||||||||||||||
| 208 | // now detach | - | ||||||||||||||||||
| 209 | // create enough space if the rest of the string needed to be percent-encoded | - | ||||||||||||||||||
| 210 | int charsProcessed = input - begin; | - | ||||||||||||||||||
| 211 | int charsRemaining = end - input; | - | ||||||||||||||||||
| 212 | int spaceNeeded = end - begin + 2 * charsRemaining + add; | - | ||||||||||||||||||
| 213 | int origSize = result.size(); | - | ||||||||||||||||||
| 214 | result.resize(origSize + spaceNeeded); | - | ||||||||||||||||||
| 215 | - | |||||||||||||||||||
| 216 | // we know that resize() above detached, so we bypass the reference count check | - | ||||||||||||||||||
| 217 | output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData())) | - | ||||||||||||||||||
| 218 | + origSize; | - | ||||||||||||||||||
| 219 | - | |||||||||||||||||||
| 220 | // copy the chars we've already processed | - | ||||||||||||||||||
| 221 | int i; | - | ||||||||||||||||||
| 222 | for (i = 0; i < charsProcessed; ++i)
| 1454-10255 | ||||||||||||||||||
| 223 | output[i] = begin[i]; executed 10255 times by 9 tests: output[i] = begin[i];Executed by:
| 10255 | ||||||||||||||||||
| 224 | output += i; | - | ||||||||||||||||||
| 225 | } executed 1454 times by 9 tests: end of blockExecuted by:
| 1454 | ||||||||||||||||||
| 226 | } executed 2776 times by 9 tests: end of blockExecuted by:
| 2776 | ||||||||||||||||||
| 227 | - | |||||||||||||||||||
| 228 | namespace { | - | ||||||||||||||||||
| 229 | struct QUrlUtf8Traits : public QUtf8BaseTraitsNoAscii | - | ||||||||||||||||||
| 230 | { | - | ||||||||||||||||||
| 231 | // override: our "bytes" are three percent-encoded UTF-16 characters | - | ||||||||||||||||||
| 232 | static void appendByte(ushort *&ptr, uchar b) | - | ||||||||||||||||||
| 233 | { | - | ||||||||||||||||||
| 234 | // b >= 0x80, by construction, so percent-encode | - | ||||||||||||||||||
| 235 | *ptr++ = '%'; | - | ||||||||||||||||||
| 236 | *ptr++ = encodeNibble(b >> 4); | - | ||||||||||||||||||
| 237 | *ptr++ = encodeNibble(b & 0xf); | - | ||||||||||||||||||
| 238 | } executed 228 times by 4 tests: end of blockExecuted by:
| 228 | ||||||||||||||||||
| 239 | - | |||||||||||||||||||
| 240 | static uchar peekByte(const ushort *ptr, int n = 0) | - | ||||||||||||||||||
| 241 | { | - | ||||||||||||||||||
| 242 | // decodePercentEncoding returns ushort(-1) if it can't decode, | - | ||||||||||||||||||
| 243 | // which means we return 0xff, which is not a valid continuation byte. | - | ||||||||||||||||||
| 244 | // If ptr[i * 3] is not '%', we'll multiply by zero and return 0, | - | ||||||||||||||||||
| 245 | // also not a valid continuation byte (if it's '%', we multiply by 1). | - | ||||||||||||||||||
| 246 | return uchar(decodePercentEncoding(ptr + n * 3)) executed 189 times by 4 tests: return uchar(decodePercentEncoding(ptr + n * 3)) * uchar(ptr[n * 3] == '%');Executed by:
| 189 | ||||||||||||||||||
| 247 | * uchar(ptr[n * 3] == '%'); executed 189 times by 4 tests: return uchar(decodePercentEncoding(ptr + n * 3)) * uchar(ptr[n * 3] == '%');Executed by:
| 189 | ||||||||||||||||||
| 248 | } | - | ||||||||||||||||||
| 249 | - | |||||||||||||||||||
| 250 | static qptrdiff availableBytes(const ushort *ptr, const ushort *end) | - | ||||||||||||||||||
| 251 | { | - | ||||||||||||||||||
| 252 | return (end - ptr) / 3; executed 154 times by 5 tests: return (end - ptr) / 3;Executed by:
| 154 | ||||||||||||||||||
| 253 | } | - | ||||||||||||||||||
| 254 | - | |||||||||||||||||||
| 255 | static void advanceByte(const ushort *&ptr, int n = 1) | - | ||||||||||||||||||
| 256 | { | - | ||||||||||||||||||
| 257 | ptr += n * 3; | - | ||||||||||||||||||
| 258 | } executed 96 times by 4 tests: end of blockExecuted by:
| 96 | ||||||||||||||||||
| 259 | }; | - | ||||||||||||||||||
| 260 | } | - | ||||||||||||||||||
| 261 | - | |||||||||||||||||||
| 262 | // returns true if we performed an UTF-8 decoding | - | ||||||||||||||||||
| 263 | static bool encodedUtf8ToUtf16(QString &result, ushort *&output, const ushort *begin, const ushort *&input, | - | ||||||||||||||||||
| 264 | const ushort *end, ushort decoded) | - | ||||||||||||||||||
| 265 | { | - | ||||||||||||||||||
| 266 | uint ucs4, *dst = &ucs4; | - | ||||||||||||||||||
| 267 | const ushort *src = input + 3;// skip the %XX that yielded \a decoded | - | ||||||||||||||||||
| 268 | int charsNeeded = QUtf8Functions::fromUtf8<QUrlUtf8Traits>(decoded, dst, src, end); | - | ||||||||||||||||||
| 269 | if (charsNeeded < 0)
| 96-213 | ||||||||||||||||||
| 270 | return false; executed 213 times by 3 tests: return false;Executed by:
| 213 | ||||||||||||||||||
| 271 | - | |||||||||||||||||||
| 272 | if (!QChar::requiresSurrogates(ucs4)) {
| 4-92 | ||||||||||||||||||
| 273 | // UTF-8 decoded and no surrogates are required | - | ||||||||||||||||||
| 274 | // detach if necessary | - | ||||||||||||||||||
| 275 | // possibilities are: 6 chars (%XX%XX) -> one char; 9 chars (%XX%XX%XX) -> one char | - | ||||||||||||||||||
| 276 | ensureDetached(result, output, begin, input, end, -3 * charsNeeded + 1); | - | ||||||||||||||||||
| 277 | *output++ = ucs4; | - | ||||||||||||||||||
| 278 | } else { executed 92 times by 4 tests: end of blockExecuted by:
| 92 | ||||||||||||||||||
| 279 | // UTF-8 decoded to something that requires a surrogate pair | - | ||||||||||||||||||
| 280 | // compressing from %XX%XX%XX%XX (12 chars) to two | - | ||||||||||||||||||
| 281 | ensureDetached(result, output, begin, input, end, -10); | - | ||||||||||||||||||
| 282 | *output++ = QChar::highSurrogate(ucs4); | - | ||||||||||||||||||
| 283 | *output++ = QChar::lowSurrogate(ucs4); | - | ||||||||||||||||||
| 284 | } executed 4 times by 2 tests: end of blockExecuted by:
| 4 | ||||||||||||||||||
| 285 | - | |||||||||||||||||||
| 286 | input = src - 1; | - | ||||||||||||||||||
| 287 | return true; executed 96 times by 4 tests: return true;Executed by:
| 96 | ||||||||||||||||||
| 288 | } | - | ||||||||||||||||||
| 289 | - | |||||||||||||||||||
| 290 | static void unicodeToEncodedUtf8(QString &result, ushort *&output, const ushort *begin, | - | ||||||||||||||||||
| 291 | const ushort *&input, const ushort *end, ushort decoded) | - | ||||||||||||||||||
| 292 | { | - | ||||||||||||||||||
| 293 | // calculate the utf8 length and ensure enough space is available | - | ||||||||||||||||||
| 294 | int utf8len = QChar::isHighSurrogate(decoded) ? 4 : decoded >= 0x800 ? 3 : 2;
| 11-87 | ||||||||||||||||||
| 295 | - | |||||||||||||||||||
| 296 | // detach | - | ||||||||||||||||||
| 297 | if (!output) {
| 15-83 | ||||||||||||||||||
| 298 | // we need 3 * utf8len for the encoded UTF-8 sequence | - | ||||||||||||||||||
| 299 | // but ensureDetached already adds 3 for the char we're processing | - | ||||||||||||||||||
| 300 | ensureDetached(result, output, begin, input, end, 3*utf8len - 3); | - | ||||||||||||||||||
| 301 | } else { executed 83 times by 4 tests: end of blockExecuted by:
| 83 | ||||||||||||||||||
| 302 | // verify that there's enough space or expand | - | ||||||||||||||||||
| 303 | int charsRemaining = end - input - 1; // not including this one | - | ||||||||||||||||||
| 304 | int pos = output - reinterpret_cast<const ushort *>(result.constData()); | - | ||||||||||||||||||
| 305 | int spaceRemaining = result.size() - pos; | - | ||||||||||||||||||
| 306 | if (spaceRemaining < 3*charsRemaining + 3*utf8len) {
| 5-10 | ||||||||||||||||||
| 307 | // must resize | - | ||||||||||||||||||
| 308 | result.resize(result.size() + 3*utf8len); | - | ||||||||||||||||||
| 309 | - | |||||||||||||||||||
| 310 | // we know that resize() above detached, so we bypass the reference count check | - | ||||||||||||||||||
| 311 | output = const_cast<ushort *>(reinterpret_cast<const ushort *>(result.constData())); | - | ||||||||||||||||||
| 312 | output += pos; | - | ||||||||||||||||||
| 313 | } executed 10 times by 2 tests: end of blockExecuted by:
| 10 | ||||||||||||||||||
| 314 | } executed 15 times by 3 tests: end of blockExecuted by:
| 15 | ||||||||||||||||||
| 315 | - | |||||||||||||||||||
| 316 | ++input; | - | ||||||||||||||||||
| 317 | int res = QUtf8Functions::toUtf8<QUrlUtf8Traits>(decoded, output, input, end); | - | ||||||||||||||||||
| 318 | --input; | - | ||||||||||||||||||
| 319 | if (res < 0) {
| 2-96 | ||||||||||||||||||
| 320 | // bad surrogate pair sequence | - | ||||||||||||||||||
| 321 | // we will encode bad UTF-16 to UTF-8 | - | ||||||||||||||||||
| 322 | // but they don't get decoded back | - | ||||||||||||||||||
| 323 | - | |||||||||||||||||||
| 324 | // first of three bytes | - | ||||||||||||||||||
| 325 | uchar c = 0xe0 | uchar(decoded >> 12); | - | ||||||||||||||||||
| 326 | *output++ = '%'; | - | ||||||||||||||||||
| 327 | *output++ = 'E'; | - | ||||||||||||||||||
| 328 | *output++ = encodeNibble(c & 0xf); | - | ||||||||||||||||||
| 329 | - | |||||||||||||||||||
| 330 | // second byte | - | ||||||||||||||||||
| 331 | c = 0x80 | (uchar(decoded >> 6) & 0x3f); | - | ||||||||||||||||||
| 332 | *output++ = '%'; | - | ||||||||||||||||||
| 333 | *output++ = encodeNibble(c >> 4); | - | ||||||||||||||||||
| 334 | *output++ = encodeNibble(c & 0xf); | - | ||||||||||||||||||
| 335 | - | |||||||||||||||||||
| 336 | // third byte | - | ||||||||||||||||||
| 337 | c = 0x80 | (decoded & 0x3f); | - | ||||||||||||||||||
| 338 | *output++ = '%'; | - | ||||||||||||||||||
| 339 | *output++ = encodeNibble(c >> 4); | - | ||||||||||||||||||
| 340 | *output++ = encodeNibble(c & 0xf); | - | ||||||||||||||||||
| 341 | } executed 2 times by 1 test: end of blockExecuted by:
| 2 | ||||||||||||||||||
| 342 | } executed 98 times by 4 tests: end of blockExecuted by:
| 98 | ||||||||||||||||||
| 343 | - | |||||||||||||||||||
| 344 | static int recode(QString &result, const ushort *begin, const ushort *end, QUrl::ComponentFormattingOptions encoding, | - | ||||||||||||||||||
| 345 | const uchar *actionTable, bool retryBadEncoding) | - | ||||||||||||||||||
| 346 | { | - | ||||||||||||||||||
| 347 | const int origSize = result.size(); | - | ||||||||||||||||||
| 348 | const ushort *input = begin; | - | ||||||||||||||||||
| 349 | ushort *output = 0; | - | ||||||||||||||||||
| 350 | - | |||||||||||||||||||
| 351 | EncodingAction action = EncodeCharacter; | - | ||||||||||||||||||
| 352 | for ( ; input != end; ++input) {
| 8018-37763 | ||||||||||||||||||
| 353 | ushort c; | - | ||||||||||||||||||
| 354 | // try a run where no change is necessary | - | ||||||||||||||||||
| 355 | for ( ; input != end; ++input) {
| 32947-782497 | ||||||||||||||||||
| 356 | c = *input; | - | ||||||||||||||||||
| 357 | if (c < 0x20U)
| 20-782477 | ||||||||||||||||||
| 358 | action = EncodeCharacter; executed 20 times by 3 tests: action = EncodeCharacter;Executed by:
| 20 | ||||||||||||||||||
| 359 | if (c < 0x20U || c >= 0x80U) // also: (c - 0x20 < 0x60U)
| 20-782477 | ||||||||||||||||||
| 360 | goto non_trivial; executed 371 times by 4 tests: goto non_trivial;Executed by:
| 371 | ||||||||||||||||||
| 361 | action = EncodingAction(actionTable[c - ' ']); | - | ||||||||||||||||||
| 362 | if (action == EncodeCharacter)
| 4445-777681 | ||||||||||||||||||
| 363 | goto non_trivial; executed 4445 times by 11 tests: goto non_trivial;Executed by:
| 4445 | ||||||||||||||||||
| 364 | if (output)
| 8347-769334 | ||||||||||||||||||
| 365 | *output++ = c; executed 8347 times by 7 tests: *output++ = c;Executed by:
| 8347 | ||||||||||||||||||
| 366 | } executed 777681 times by 52 tests: end of blockExecuted by:
| 777681 | ||||||||||||||||||
| 367 | break; executed 32947 times by 52 tests: break;Executed by:
| 32947 | ||||||||||||||||||
| 368 | - | |||||||||||||||||||
| 369 | non_trivial: | - | ||||||||||||||||||
| 370 | uint decoded; | - | ||||||||||||||||||
| 371 | if (c == '%' && retryBadEncoding) {
| 103-2473 | ||||||||||||||||||
| 372 | // always write "%25" | - | ||||||||||||||||||
| 373 | ensureDetached(result, output, begin, input, end); | - | ||||||||||||||||||
| 374 | *output++ = '%'; | - | ||||||||||||||||||
| 375 | *output++ = '2'; | - | ||||||||||||||||||
| 376 | *output++ = '5'; | - | ||||||||||||||||||
| 377 | continue; executed 103 times by 4 tests: continue;Executed by:
| 103 | ||||||||||||||||||
| 378 | } else if (c == '%') {
| 2343-2370 | ||||||||||||||||||
| 379 | // check if the input is valid | - | ||||||||||||||||||
| 380 | if (input + 2 >= end || (decoded = decodePercentEncoding(input)) == ushort(-1)) {
| 30-2333 | ||||||||||||||||||
| 381 | // not valid, retry | - | ||||||||||||||||||
| 382 | result.resize(origSize); | - | ||||||||||||||||||
| 383 | return recode(result, begin, end, encoding, actionTable, true); executed 67 times by 4 tests: return recode(result, begin, end, encoding, actionTable, true);Executed by:
| 67 | ||||||||||||||||||
| 384 | } | - | ||||||||||||||||||
| 385 | - | |||||||||||||||||||
| 386 | if (decoded >= 0x80) {
| 624-1679 | ||||||||||||||||||
| 387 | // decode the UTF-8 sequence | - | ||||||||||||||||||
| 388 | if (!(encoding & QUrl::EncodeUnicode) &&
| 309-315 | ||||||||||||||||||
| 389 | encodedUtf8ToUtf16(result, output, begin, input, end, decoded))
| 96-213 | ||||||||||||||||||
| 390 | continue; executed 96 times by 4 tests: continue;Executed by:
| 96 | ||||||||||||||||||
| 391 | - | |||||||||||||||||||
| 392 | // decoding the encoded UTF-8 failed | - | ||||||||||||||||||
| 393 | action = LeaveCharacter; | - | ||||||||||||||||||
| 394 | } else if (decoded >= 0x20) { executed 528 times by 3 tests: end of blockExecuted by:
| 335-1344 | ||||||||||||||||||
| 395 | action = EncodingAction(actionTable[decoded - ' ']); | - | ||||||||||||||||||
| 396 | } executed 1344 times by 9 tests: end of blockExecuted by:
| 1344 | ||||||||||||||||||
| 397 | } else { executed 2207 times by 9 tests: end of blockExecuted by:
| 2207 | ||||||||||||||||||
| 398 | decoded = c; | - | ||||||||||||||||||
| 399 | if (decoded >= 0x80 && encoding & QUrl::EncodeUnicode) {
| 351-1992 | ||||||||||||||||||
| 400 | // encode the UTF-8 sequence | - | ||||||||||||||||||
| 401 | unicodeToEncodedUtf8(result, output, begin, input, end, decoded); | - | ||||||||||||||||||
| 402 | continue; executed 98 times by 4 tests: continue;Executed by:
| 98 | ||||||||||||||||||
| 403 | } else if (decoded >= 0x80) {
| 253-1992 | ||||||||||||||||||
| 404 | if (output)
| 0-253 | ||||||||||||||||||
| 405 | *output++ = c; never executed: *output++ = c; | 0 | ||||||||||||||||||
| 406 | continue; executed 253 times by 3 tests: continue;Executed by:
| 253 | ||||||||||||||||||
| 407 | } | - | ||||||||||||||||||
| 408 | } executed 1992 times by 8 tests: end of blockExecuted by:
| 1992 | ||||||||||||||||||
| 409 | - | |||||||||||||||||||
| 410 | // there are six possibilities: | - | ||||||||||||||||||
| 411 | // current \ action | DecodeCharacter | LeaveCharacter | EncodeCharacter | - | ||||||||||||||||||
| 412 | // decoded | 1:leave | 2:leave | 3:encode | - | ||||||||||||||||||
| 413 | // encoded | 4:decode | 5:leave | 6:leave | - | ||||||||||||||||||
| 414 | // cases 1 and 2 were handled before this section | - | ||||||||||||||||||
| 415 | - | |||||||||||||||||||
| 416 | if (c == '%' && action != DecodeCharacter) {
| 378-2207 | ||||||||||||||||||
| 417 | // cases 5 and 6: it's encoded and we're leaving it as it is | - | ||||||||||||||||||
| 418 | // except we're pedantic and we'll uppercase the hex | - | ||||||||||||||||||
| 419 | if (output || !isUpperHex(input[1]) || !isUpperHex(input[2])) {
| 7-1733 | ||||||||||||||||||
| 420 | ensureDetached(result, output, begin, input, end); | - | ||||||||||||||||||
| 421 | *output++ = '%'; | - | ||||||||||||||||||
| 422 | *output++ = toUpperHex(*++input); | - | ||||||||||||||||||
| 423 | *output++ = toUpperHex(*++input); | - | ||||||||||||||||||
| 424 | } executed 124 times by 4 tests: end of blockExecuted by:
| 124 | ||||||||||||||||||
| 425 | } else if (c == '%' && action == DecodeCharacter) { executed 1829 times by 6 tests: end of blockExecuted by:
| 0-1992 | ||||||||||||||||||
| 426 | // case 4: we need to decode | - | ||||||||||||||||||
| 427 | ensureDetached(result, output, begin, input, end); | - | ||||||||||||||||||
| 428 | *output++ = decoded; | - | ||||||||||||||||||
| 429 | input += 2; | - | ||||||||||||||||||
| 430 | } else { executed 378 times by 7 tests: end of blockExecuted by:
| 378 | ||||||||||||||||||
| 431 | // must be case 3: we need to encode | - | ||||||||||||||||||
| 432 | ensureDetached(result, output, begin, input, end); | - | ||||||||||||||||||
| 433 | *output++ = '%'; | - | ||||||||||||||||||
| 434 | *output++ = encodeNibble(c >> 4); | - | ||||||||||||||||||
| 435 | *output++ = encodeNibble(c & 0xf); | - | ||||||||||||||||||
| 436 | } executed 1992 times by 8 tests: end of blockExecuted by:
| 1992 | ||||||||||||||||||
| 437 | } | - | ||||||||||||||||||
| 438 | - | |||||||||||||||||||
| 439 | if (output) {
| 1452-39513 | ||||||||||||||||||
| 440 | int len = output - reinterpret_cast<const ushort *>(result.constData()); | - | ||||||||||||||||||
| 441 | result.truncate(len); | - | ||||||||||||||||||
| 442 | return len - origSize; executed 1452 times by 9 tests: return len - origSize;Executed by:
| 1452 | ||||||||||||||||||
| 443 | } | - | ||||||||||||||||||
| 444 | return 0; executed 39513 times by 52 tests: return 0;Executed by:
| 39513 | ||||||||||||||||||
| 445 | } | - | ||||||||||||||||||
| 446 | - | |||||||||||||||||||
| 447 | /*! | - | ||||||||||||||||||
| 448 | \since 5.0 | - | ||||||||||||||||||
| 449 | \internal | - | ||||||||||||||||||
| 450 | - | |||||||||||||||||||
| 451 | This function decodes a percent-encoded string located from \a begin to \a | - | ||||||||||||||||||
| 452 | end, by appending each character to \a appendTo. It returns the number of | - | ||||||||||||||||||
| 453 | characters appended. Each percent-encoded sequence is decoded as follows: | - | ||||||||||||||||||
| 454 | - | |||||||||||||||||||
| 455 | \list | - | ||||||||||||||||||
| 456 | \li from %00 to %7F: the exact decoded value is appended; | - | ||||||||||||||||||
| 457 | \li from %80 to %FF: QChar::ReplacementCharacter is appended; | - | ||||||||||||||||||
| 458 | \li bad encoding: original input is copied to the output, undecoded. | - | ||||||||||||||||||
| 459 | \endlist | - | ||||||||||||||||||
| 460 | - | |||||||||||||||||||
| 461 | Given the above, it's important for the input to already have all UTF-8 | - | ||||||||||||||||||
| 462 | percent sequences decoded by qt_urlRecode (that is, the input should not | - | ||||||||||||||||||
| 463 | have been processed with QUrl::EncodeUnicode). | - | ||||||||||||||||||
| 464 | - | |||||||||||||||||||
| 465 | The input should also be a valid percent-encoded sequence (the output of | - | ||||||||||||||||||
| 466 | qt_urlRecode is always valid). | - | ||||||||||||||||||
| 467 | */ | - | ||||||||||||||||||
| 468 | static int decode(QString &appendTo, const ushort *begin, const ushort *end) | - | ||||||||||||||||||
| 469 | { | - | ||||||||||||||||||
| 470 | const int origSize = appendTo.size(); | - | ||||||||||||||||||
| 471 | const ushort *input = begin; | - | ||||||||||||||||||
| 472 | ushort *output = 0; | - | ||||||||||||||||||
| 473 | while (input != end) {
| 16464-623611 | ||||||||||||||||||
| 474 | if (*input != '%') {
| 107-623504 | ||||||||||||||||||
| 475 | if (output)
| 142-623362 | ||||||||||||||||||
| 476 | *output++ = *input; executed 142 times by 2 tests: *output++ = *input;Executed by:
| 142 | ||||||||||||||||||
| 477 | ++input; | - | ||||||||||||||||||
| 478 | continue; executed 623504 times by 22 tests: continue;Executed by:
| 623504 | ||||||||||||||||||
| 479 | } | - | ||||||||||||||||||
| 480 | - | |||||||||||||||||||
| 481 | if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) {
| 23-84 | ||||||||||||||||||
| 482 | // badly-encoded data | - | ||||||||||||||||||
| 483 | appendTo.resize(origSize + (end - begin)); | - | ||||||||||||||||||
| 484 | memcpy(appendTo.begin() + origSize, begin, (end - begin) * sizeof(ushort)); | - | ||||||||||||||||||
| 485 | return end - begin; executed 23 times by 2 tests: return end - begin;Executed by:
| 23 | ||||||||||||||||||
| 486 | } | - | ||||||||||||||||||
| 487 | - | |||||||||||||||||||
| 488 | if (Q_UNLIKELY(!output)) {
| 39-45 | ||||||||||||||||||
| 489 | // detach | - | ||||||||||||||||||
| 490 | appendTo.resize(origSize + (end - begin)); | - | ||||||||||||||||||
| 491 | output = reinterpret_cast<ushort *>(appendTo.begin()) + origSize; | - | ||||||||||||||||||
| 492 | memcpy(output, begin, (input - begin) * sizeof(ushort)); | - | ||||||||||||||||||
| 493 | output += input - begin; | - | ||||||||||||||||||
| 494 | } executed 45 times by 2 tests: end of blockExecuted by:
| 45 | ||||||||||||||||||
| 495 | - | |||||||||||||||||||
| 496 | ++input; | - | ||||||||||||||||||
| 497 | *output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]); | - | ||||||||||||||||||
| 498 | if (output[-1] >= 0x80)
| 18-66 | ||||||||||||||||||
| 499 | output[-1] = QChar::ReplacementCharacter; executed 18 times by 1 test: output[-1] = QChar::ReplacementCharacter;Executed by:
| 18 | ||||||||||||||||||
| 500 | input += 2; | - | ||||||||||||||||||
| 501 | } executed 84 times by 2 tests: end of blockExecuted by:
| 84 | ||||||||||||||||||
| 502 | - | |||||||||||||||||||
| 503 | if (output) {
| 34-16430 | ||||||||||||||||||
| 504 | int len = output - reinterpret_cast<ushort *>(appendTo.begin()); | - | ||||||||||||||||||
| 505 | appendTo.truncate(len); | - | ||||||||||||||||||
| 506 | return len - origSize; executed 34 times by 2 tests: return len - origSize;Executed by:
| 34 | ||||||||||||||||||
| 507 | } | - | ||||||||||||||||||
| 508 | return 0; executed 16430 times by 26 tests: return 0;Executed by:
| 16430 | ||||||||||||||||||
| 509 | } | - | ||||||||||||||||||
| 510 | - | |||||||||||||||||||
| 511 | template <size_t N> | - | ||||||||||||||||||
| 512 | static void maskTable(uchar (&table)[N], const uchar (&mask)[N]) | - | ||||||||||||||||||
| 513 | { | - | ||||||||||||||||||
| 514 | for (size_t i = 0; i < N; ++i)
| 709-68064 | ||||||||||||||||||
| 515 | table[i] &= mask[i]; executed 68064 times by 4 tests: table[i] &= mask[i];Executed by:
| 68064 | ||||||||||||||||||
| 516 | } executed 709 times by 4 tests: end of blockExecuted by:
| 709 | ||||||||||||||||||
| 517 | - | |||||||||||||||||||
| 518 | /*! | - | ||||||||||||||||||
| 519 | \internal | - | ||||||||||||||||||
| 520 | - | |||||||||||||||||||
| 521 | Recodes the string from \a begin to \a end. If any transformations are | - | ||||||||||||||||||
| 522 | done, append them to \a appendTo and return the number of characters added. | - | ||||||||||||||||||
| 523 | If no transformations were required, return 0. | - | ||||||||||||||||||
| 524 | - | |||||||||||||||||||
| 525 | The \a encoding option modifies the default behaviour: | - | ||||||||||||||||||
| 526 | \list | - | ||||||||||||||||||
| 527 | \li QUrl::DecodeReserved: if set, reserved characters will be decoded; | - | ||||||||||||||||||
| 528 | if unset, reserved characters will be encoded | - | ||||||||||||||||||
| 529 | \li QUrl::EncodeSpaces: if set, spaces will be encoded to "%20"; if unset, they will be " " | - | ||||||||||||||||||
| 530 | \li QUrl::EncodeUnicode: if set, characters above U+0080 will be encoded to their UTF-8 | - | ||||||||||||||||||
| 531 | percent-encoded form; if unset, they will be decoded to UTF-16 | - | ||||||||||||||||||
| 532 | \li QUrl::FullyDecoded: if set, this function will decode all percent-encoded sequences, | - | ||||||||||||||||||
| 533 | including that of the percent character. The resulting string | - | ||||||||||||||||||
| 534 | will not be percent-encoded anymore. Use with caution! | - | ||||||||||||||||||
| 535 | In this mode, the behaviour is undefined if the input string | - | ||||||||||||||||||
| 536 | contains any percent-encoding sequences above %80. | - | ||||||||||||||||||
| 537 | Also, the function will not correct bad % sequences. | - | ||||||||||||||||||
| 538 | \endlist | - | ||||||||||||||||||
| 539 | - | |||||||||||||||||||
| 540 | Other flags are ignored (including QUrl::EncodeReserved). | - | ||||||||||||||||||
| 541 | - | |||||||||||||||||||
| 542 | The \a tableModifications argument can be used to supply extra | - | ||||||||||||||||||
| 543 | modifications to the tables, to be applied after the flags above are | - | ||||||||||||||||||
| 544 | handled. It consists of a sequence of 16-bit values, where the low 8 bits | - | ||||||||||||||||||
| 545 | indicate the character in question and the high 8 bits are either \c | - | ||||||||||||||||||
| 546 | EncodeCharacter, \c LeaveCharacter or \c DecodeCharacter. | - | ||||||||||||||||||
| 547 | - | |||||||||||||||||||
| 548 | This function corrects percent-encoded errors by interpreting every '%' as | - | ||||||||||||||||||
| 549 | meaning "%25" (all percents in the same content). | - | ||||||||||||||||||
| 550 | */ | - | ||||||||||||||||||
| 551 | - | |||||||||||||||||||
| 552 | Q_AUTOTEST_EXPORT int | - | ||||||||||||||||||
| 553 | qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end, | - | ||||||||||||||||||
| 554 | QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications) | - | ||||||||||||||||||
| 555 | { | - | ||||||||||||||||||
| 556 | uchar actionTable[sizeof defaultActionTable]; | - | ||||||||||||||||||
| 557 | if (encoding == QUrl::FullyDecoded) {
| 16487-40965 | ||||||||||||||||||
| 558 | return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end)); executed 16487 times by 26 tests: return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end));Executed by:
| 16487 | ||||||||||||||||||
| 559 | } | - | ||||||||||||||||||
| 560 | - | |||||||||||||||||||
| 561 | memcpy(actionTable, defaultActionTable, sizeof actionTable); | - | ||||||||||||||||||
| 562 | if (encoding & QUrl::DecodeReserved)
| 709-40256 | ||||||||||||||||||
| 563 | maskTable(actionTable, reservedMask); executed 709 times by 4 tests: maskTable(actionTable, reservedMask);Executed by:
| 709 | ||||||||||||||||||
| 564 | if (!(encoding & QUrl::EncodeSpaces))
| 6513-34452 | ||||||||||||||||||
| 565 | actionTable[0] = DecodeCharacter; // decode executed 34452 times by 52 tests: actionTable[0] = DecodeCharacter;Executed by:
| 34452 | ||||||||||||||||||
| 566 | - | |||||||||||||||||||
| 567 | if (tableModifications) {
| 10784-30181 | ||||||||||||||||||
| 568 | for (const ushort *p = tableModifications; *p; ++p)
| 30181-234767 | ||||||||||||||||||
| 569 | actionTable[uchar(*p) - ' '] = *p >> 8; executed 234767 times by 38 tests: actionTable[uchar(*p) - ' '] = *p >> 8;Executed by:
| 234767 | ||||||||||||||||||
| 570 | } executed 30181 times by 38 tests: end of blockExecuted by:
| 30181 | ||||||||||||||||||
| 571 | - | |||||||||||||||||||
| 572 | return recode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end), executed 40965 times by 52 tests: return recode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end), encoding, actionTable, false);Executed by:
| 40965 | ||||||||||||||||||
| 573 | encoding, actionTable, false); executed 40965 times by 52 tests: return recode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(end), encoding, actionTable, false);Executed by:
| 40965 | ||||||||||||||||||
| 574 | } | - | ||||||||||||||||||
| 575 | - | |||||||||||||||||||
| 576 | /*! | - | ||||||||||||||||||
| 577 | \internal | - | ||||||||||||||||||
| 578 | \since 5.0 | - | ||||||||||||||||||
| 579 | - | |||||||||||||||||||
| 580 | \a ba contains an 8-bit form of the component and it might be | - | ||||||||||||||||||
| 581 | percent-encoded already. We can't use QString::fromUtf8 because it might | - | ||||||||||||||||||
| 582 | contain non-UTF8 sequences. We can't use QByteArray::toPercentEncoding | - | ||||||||||||||||||
| 583 | because it might already contain percent-encoded sequences. We can't use | - | ||||||||||||||||||
| 584 | qt_urlRecode because it needs UTF-16 input. | - | ||||||||||||||||||
| 585 | */ | - | ||||||||||||||||||
| 586 | Q_AUTOTEST_EXPORT | - | ||||||||||||||||||
| 587 | QString qt_urlRecodeByteArray(const QByteArray &ba) | - | ||||||||||||||||||
| 588 | { | - | ||||||||||||||||||
| 589 | if (ba.isNull())
| 3-40 | ||||||||||||||||||
| 590 | return QString(); executed 3 times by 2 tests: return QString();Executed by:
| 3 | ||||||||||||||||||
| 591 | - | |||||||||||||||||||
| 592 | // scan ba for anything above or equal to 0x80 | - | ||||||||||||||||||
| 593 | // control points below 0x20 are fine in QString | - | ||||||||||||||||||
| 594 | const char *in = ba.constData(); | - | ||||||||||||||||||
| 595 | const char *const end = ba.constEnd(); | - | ||||||||||||||||||
| 596 | for ( ; in < end; ++in) {
| 35-552 | ||||||||||||||||||
| 597 | if (*in & 0x80)
| 5-547 | ||||||||||||||||||
| 598 | break; executed 5 times by 2 tests: break;Executed by:
| 5 | ||||||||||||||||||
| 599 | } executed 547 times by 2 tests: end of blockExecuted by:
| 547 | ||||||||||||||||||
| 600 | - | |||||||||||||||||||
| 601 | if (in == end) {
| 5-35 | ||||||||||||||||||
| 602 | // no non-ASCII found, we're safe to convert to QString | - | ||||||||||||||||||
| 603 | return QString::fromLatin1(ba, ba.size()); executed 35 times by 2 tests: return QString::fromLatin1(ba, ba.size());Executed by:
| 35 | ||||||||||||||||||
| 604 | } | - | ||||||||||||||||||
| 605 | - | |||||||||||||||||||
| 606 | // we found something that we need to encode | - | ||||||||||||||||||
| 607 | QByteArray intermediate = ba; | - | ||||||||||||||||||
| 608 | intermediate.resize(ba.size() * 3 - (in - ba.constData())); | - | ||||||||||||||||||
| 609 | uchar *out = reinterpret_cast<uchar *>(intermediate.data() + (in - ba.constData())); | - | ||||||||||||||||||
| 610 | for ( ; in < end; ++in) {
| 5-10 | ||||||||||||||||||
| 611 | if (*in & 0x80) {
| 0-10 | ||||||||||||||||||
| 612 | // encode | - | ||||||||||||||||||
| 613 | *out++ = '%'; | - | ||||||||||||||||||
| 614 | *out++ = encodeNibble(uchar(*in) >> 4); | - | ||||||||||||||||||
| 615 | *out++ = encodeNibble(uchar(*in) & 0xf); | - | ||||||||||||||||||
| 616 | } else { executed 10 times by 2 tests: end of blockExecuted by:
| 10 | ||||||||||||||||||
| 617 | // keep | - | ||||||||||||||||||
| 618 | *out++ = uchar(*in); | - | ||||||||||||||||||
| 619 | } never executed: end of block | 0 | ||||||||||||||||||
| 620 | } | - | ||||||||||||||||||
| 621 | - | |||||||||||||||||||
| 622 | // now it's safe to call fromLatin1 | - | ||||||||||||||||||
| 623 | return QString::fromLatin1(intermediate, out - reinterpret_cast<uchar *>(intermediate.data())); executed 5 times by 2 tests: return QString::fromLatin1(intermediate, out - reinterpret_cast<uchar *>(intermediate.data()));Executed by:
| 5 | ||||||||||||||||||
| 624 | } | - | ||||||||||||||||||
| 625 | - | |||||||||||||||||||
| 626 | QT_END_NAMESPACE | - | ||||||||||||||||||
| Source code | Switch to Preprocessed file |