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:
parent
993bbb4d4b
commit
2ff719de8f
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user