diff options
-rw-r--r-- | src/corelib/io/qurlrecode.cpp | 13 | ||||
-rw-r--r-- | tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp | 14 |
2 files changed, 21 insertions, 6 deletions
diff --git a/src/corelib/io/qurlrecode.cpp b/src/corelib/io/qurlrecode.cpp index 5ff0c40a4f..509a92d2b0 100644 --- a/src/corelib/io/qurlrecode.cpp +++ b/src/corelib/io/qurlrecode.cpp @@ -573,6 +573,13 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end) continue; } + if (Q_UNLIKELY(end - input < 3 || !isHex(input[1]) || !isHex(input[2]))) { + // badly-encoded data + appendTo.resize(origSize + (end - begin)); + memcpy(appendTo.begin() + origSize, begin, (end - begin) * sizeof(ushort)); + return end - begin; + } + if (Q_UNLIKELY(!output)) { // detach appendTo.resize(origSize + (end - begin)); @@ -582,9 +589,6 @@ static int decode(QString &appendTo, const ushort *begin, const ushort *end) } ++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; } @@ -635,6 +639,9 @@ static void maskTable(uchar (&table)[N], const uchar (&mask)[N]) handled. It consists of a sequence of 16-bit values, where the low 8 bits indicate the character in question and the high 8 bits are either \c EncodeCharacter, \c LeaveCharacter or \c DecodeCharacter. + + This function corrects percent-encoded errors by interpreting every '%' as + meaning "%25" (all percents in the same content). */ Q_AUTOTEST_EXPORT int diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 2014045171..b39b34e494 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -824,12 +824,20 @@ void tst_QUrlInternal::correctEncodedMistakes() QFETCH(QString, expected); // prepend some data to be sure that it remains there - QString output = QTest::currentDataTag(); - expected.prepend(output); + QString dataTag = QTest::currentDataTag(); + QString output = dataTag; if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), 0)) output += input; - QCOMPARE(output, expected); + QCOMPARE(output, dataTag + expected); + + // now try the full decode mode + output = dataTag; + QString expected2 = QUrl::fromPercentEncoding(expected.toLatin1()); + + if (!qt_urlRecode(output, input.constData(), input.constData() + input.length(), QUrl::FullyDecoded)) + output += input; + QCOMPARE(output, dataTag + expected2); } static void addUtf8Data(const char *name, const char *data) |