From 2ff719de8fe7a6ec40d1e085ad3211a4fd09fe69 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 1 Jul 2013 17:52:18 -0700 Subject: [PATCH] QUrlQuery: update our understanding of delimiters This commit is similar to the previous commit that changed the behavior of QUrl, but now to QUrlQuery. We can now remove a section of qt_urlDecode, which is no longer used: there's no "decode everything" mode anymore. Task-number: QTBUG-31660 Change-Id: I66cfbfd290eeba5b04688cd5ffd615dd57cc6309 Reviewed-by: David Faure (KDE) --- src/corelib/io/qurlquery.cpp | 41 +++++++++++++++++++---------------- src/corelib/io/qurlrecode.cpp | 21 +++++------------- 2 files changed, 27 insertions(+), 35 deletions(-) diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 547084840f..731fea257e 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -191,12 +191,9 @@ template<> void QSharedDataPointer::detach() // the getter methods, when called with the default encoding value, will not // have to recode anything (except for toString()). // -// The "+" sub-delimiter is always left untouched. We never encode "+" to "%2B" -// nor do we decode "%2B" to "+", no matter what the user asks. -// -// The rest of the delimiters are kept in their decoded forms and that's -// considered non-ambiguous. That includes the pair and value delimiters -// themselves. +// QUrlQuery handling of delimiters is quite simple: we never touch any of +// them, except for the "#" character and the pair and value delimiters. Those +// are always kept in their decoded forms. // // But when recreating the query string, in toString(), we must take care of // the special delimiters: the pair and value delimiters, as well as the "#" @@ -205,12 +202,17 @@ template<> void QSharedDataPointer::detach() #define decode(x) ushort(x) #define leave(x) ushort(0x100 | (x)) #define encode(x) ushort(0x200 | (x)) -static const ushort prettyDecodedActions[] = { leave('+'), 0 }; inline QString QUrlQueryPrivate::recodeFromUser(const QString &input) const { // note: duplicated in setQuery() QString output; + ushort prettyDecodedActions[] = { + decode(pairDelimiter.unicode()), + decode(valueDelimiter.unicode()), + decode('#'), + 0 + }; if (qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::DecodeReserved, prettyDecodedActions)) @@ -233,7 +235,7 @@ inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::Compon if (!(encoding & QUrl::EncodeDelimiters)) { QString output; if (qt_urlRecode(output, input.constData(), input.constData() + input.length(), - encoding, prettyDecodedActions)) + encoding, 0)) return output; return input; } @@ -249,6 +251,13 @@ inline QString QUrlQueryPrivate::recodeToUser(const QString &input, QUrl::Compon void QUrlQueryPrivate::setQuery(const QString &query) { + ushort prettyDecodedActions[] = { + decode(pairDelimiter.unicode()), + decode(valueDelimiter.unicode()), + decode('#'), + 0 + }; + itemList.clear(); const QChar *pos = query.constData(); const QChar *const end = pos + query.size(); @@ -461,24 +470,18 @@ QString QUrlQuery::query(QUrl::ComponentFormattingOptions encoding) const return QString(); // unlike the component encoding, for the whole query we need to modify a little: - // - the "#" character is ambiguous, so we decode it only in DecodeAllDelimiters mode + // - the "#" character is unambiguous, so we encode it in EncodeDelimiters mode // - the query delimiter pair must always be encoded - // - the non-delimiters vary on DecodeUnambiguousDelimiters - // so: - // - full encoding: encode the non-delimiters, the pair, "#", "[" and "]" - // - pretty decode: decode the non-delimiters, "[" and "]"; encode the pair and "#" - // - decode all: decode the non-delimiters, "[", "]", "#"; encode the pair // start with what's always encoded ushort tableActions[] = { - leave('+'), // 0 - encode(d->pairDelimiter.unicode()), // 1 - encode(d->valueDelimiter.unicode()), // 2 - decode('#'), // 3 + encode(d->pairDelimiter.unicode()), // 0 + encode(d->valueDelimiter.unicode()), // 1 + 0, // 2 0 }; if (encoding & QUrl::EncodeDelimiters) { - tableActions[3] = encode('#'); + tableActions[2] = encode('#'); } QString result; diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp index 9189cd294f..e4f37574a3 100644 --- a/src/corelib/io/qurlrecode.cpp +++ b/src/corelib/io/qurlrecode.cpp @@ -598,22 +598,11 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end, return decode(appendTo, reinterpret_cast(begin), reinterpret_cast(end)); } - if (!(encoding & QUrl::EncodeDelimiters) && encoding & QUrl::DecodeReserved) { - // reset the table - memset(actionTable, DecodeCharacter, sizeof actionTable); - if (encoding & QUrl::EncodeSpaces) - actionTable[0] = EncodeCharacter; - - // these are always encoded - actionTable['%' - ' '] = EncodeCharacter; - actionTable[0x7F - ' '] = EncodeCharacter; - } else { - memcpy(actionTable, defaultActionTable, sizeof actionTable); - if (encoding & QUrl::DecodeReserved) - maskTable(actionTable, reservedMask); - if (!(encoding & QUrl::EncodeSpaces)) - actionTable[0] = DecodeCharacter; // decode - } + memcpy(actionTable, defaultActionTable, sizeof actionTable); + if (encoding & QUrl::DecodeReserved) + maskTable(actionTable, reservedMask); + if (!(encoding & QUrl::EncodeSpaces)) + actionTable[0] = DecodeCharacter; // decode if (tableModifications) { for (const ushort *p = tableModifications; *p; ++p)