QUrl: fix mismatch of encoded/decoded spaces in setXxx

Amends commit d064c26d2c1fb1f78013031a83b661ef6f74ce21, which introduced
qt_encodeFromUser(). As far as I can tell and test, only the space
character was an exception, due to this code in qt_urlRecode():

    if (!(encoding & QUrl::EncodeSpaces))
        actionTable[0] = DecodeCharacter; // decode

That meant that encoded spaces was an opt-in, not an opt-out, but is not
the default in the defaultActionTable. This was missed in the new
function.

Fixes: QTBUG-135949
Change-Id: Ic8d2adac5c32f858748bfffd5654aac3c7a2f782
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
This commit is contained in:
Thiago Macieira 2025-04-14 09:18:05 -07:00
parent 756766eaa0
commit d3758ce9b0
2 changed files with 22 additions and 0 deletions

View File

@ -669,6 +669,9 @@ qsizetype qt_encodeFromUser(QString &appendTo, const QString &in, const ushort *
actionTable['[' - ' '] = EncodeCharacter;
actionTable[']' - ' '] = EncodeCharacter;
// Apply !EncodeSpaces, same as qt_urlRecode() above
actionTable[0] = DecodeCharacter;
if (tableModifications) {
for (const ushort *p = tableModifications; *p; ++p)
actionTable[uchar(*p) - ' '] = *p >> 8;

View File

@ -334,6 +334,25 @@ void tst_QUrl::comparison()
QCOMPARE(url4EncodedDots.toString(), QString("example://a/.//b/..%2F/b/c/"));
QCOMPARE(url4EncodedDots.adjusted(QUrl::NormalizePathSegments).toString(), QString("example://a//b/..%2F/b/c/"));
QUrl urlPathSetDecoded = QUrl("ws://localhost:12345/segment/with spaces/<é>", QUrl::TolerantMode);
QUrl urlPathSetEncoded = QUrl("ws://localhost:12345/segment/with%20spaces/%3C%c3%a9%3E", QUrl::TolerantMode);
QCOMPARE(urlPathSetDecoded, urlPathSetEncoded);
QUrl urlSetPathEncodedWithPercent = QUrl("ws://localhost:12345");
urlSetPathEncodedWithPercent.setPath("/segment/with%20spaces/%3C%c3%a9%3E", QUrl::TolerantMode);
QUrl urlSetPathEncodedWithLiterals = QUrl("ws://localhost:12345");
urlSetPathEncodedWithLiterals.setPath("/segment/with spaces/<é>", QUrl::TolerantMode);
QUrl urlSetPathDecoded = QUrl("ws://localhost:12345");
urlSetPathDecoded.setPath("/segment/with spaces/<é>", QUrl::DecodedMode);
QCOMPARE(urlSetPathEncodedWithPercent, urlPathSetEncoded);
QCOMPARE(urlSetPathEncodedWithPercent, urlPathSetDecoded);
QCOMPARE(urlSetPathEncodedWithLiterals, urlPathSetEncoded);
QCOMPARE(urlSetPathEncodedWithLiterals, urlPathSetDecoded);
QCOMPARE(urlSetPathEncodedWithLiterals, urlSetPathEncodedWithPercent);
QCOMPARE(urlSetPathDecoded, urlPathSetEncoded);
QCOMPARE(urlSetPathDecoded, urlPathSetDecoded);
QCOMPARE(urlSetPathDecoded, urlSetPathEncodedWithPercent);
QCOMPARE(urlSetPathDecoded, urlSetPathEncodedWithLiterals);
// 6.2.2.1 Make sure hexdecimal characters in percent encoding are
// treated case-insensitively
QUrl url5;