From 1ca791faf5b89c35b4b39d443d2118a882c3946b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 21 May 2012 20:21:16 +0200 Subject: Add the QUrl::FullyDecoded flag to the component formatting This allows the QUrl component getters to return fully decoded data, like they did in Qt 4. This is necessary for some use-cases where the component like the user name, password or path are used outside the context of a URL. In those contexts, the percent-encoded data makes no sense, and the loss of data of what could be represented in a URL is acceptable. Also take the opportunity to expand the documentation of those getter methods, explaining what the options argument does. Discussed-on: http://lists.qt-project.org/pipermail/development/2012-May/003811.html Change-Id: I89f743cde78c02f169c88314bff0768714341419 Reviewed-by: Lars Knoll Reviewed-by: David Faure Reviewed-by: Shane Kearns --- src/corelib/io/qurlrecode.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'src/corelib/io/qurlrecode.cpp') diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp index 3d985dbdc0..12d23e9450 100644 --- a/src/corelib/io/qurlrecode.cpp +++ b/src/corelib/io/qurlrecode.cpp @@ -560,6 +560,43 @@ non_trivial: return 0; } +static int decode(QString &appendTo, const ushort *begin, const ushort *end) +{ + const int origSize = appendTo.size(); + const ushort *input = begin; + ushort *output = 0; + while (input != end) { + if (*input != '%') { + if (output) + *output++ = *input; + ++input; + continue; + } + + if (Q_UNLIKELY(!output)) { + // detach + appendTo.resize(origSize + (end - begin)); + output = reinterpret_cast(appendTo.begin()) + origSize; + memcpy(output, begin, (input - begin) * sizeof(ushort)); + output += input - begin; + } + + ++input; + Q_ASSERT(input <= end - 2); // we need two characters + Q_ASSERT(isHex(input[0])); + Q_ASSERT(isHex(input[1])); + *output++ = decodeNibble(input[0]) << 4 | decodeNibble(input[1]); + input += 2; + } + + if (output) { + int len = output - reinterpret_cast(appendTo.begin()); + appendTo.truncate(len); + return len - origSize; + } + return 0; +} + template static void maskTable(uchar (&table)[N], const uchar (&mask)[N]) { @@ -583,6 +620,12 @@ static void maskTable(uchar (&table)[N], const uchar (&mask)[N]) \li QUrl::EncodeSpaces: if set, spaces will be encoded to "%20"; if unset, they will be " " \li QUrl::EncodeUnicode: if set, characters above U+0080 will be encoded to their UTF-8 percent-encoded form; if unset, they will be decoded to UTF-16 + \li QUrl::FullyDecoded: if set, this function will decode all percent-encoded sequences, + including that of the percent character. The resulting string + will not be percent-encoded anymore. Use with caution! + In this mode, the behaviour is undefined if the input string + contains any percent-encoding sequences above %80. + Also, the function will not correct bad % sequences. \endlist Other flags are ignored (including QUrl::EncodeReserved). @@ -599,6 +642,10 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end, QUrl::ComponentFormattingOptions encoding, const ushort *tableModifications) { uchar actionTable[sizeof defaultActionTable]; + if (encoding == QUrl::FullyDecoded) { + return decode(appendTo, reinterpret_cast(begin), reinterpret_cast(end)); + } + if (!(encoding & QUrl::EncodeDelimiters) && encoding & QUrl::DecodeReserved) { // reset the table memset(actionTable, DecodeCharacter, sizeof actionTable); -- cgit v1.2.3