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) <faure@kde.org>
This commit is contained in:
Thiago Macieira 2013-07-01 17:52:18 -07:00 committed by The Qt Project
parent 993bbb4d4b
commit 2ff719de8f
2 changed files with 27 additions and 35 deletions

View File

@ -191,12 +191,9 @@ template<> void QSharedDataPointer<QUrlQueryPrivate>::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<QUrlQueryPrivate>::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;

View File

@ -598,22 +598,11 @@ qt_urlRecode(QString &appendTo, const QChar *begin, const QChar *end,
return decode(appendTo, reinterpret_cast<const ushort *>(begin), reinterpret_cast<const ushort *>(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)