From 2b4ffe914f191f598ae8e9639ad1efd3179e4b46 Mon Sep 17 00:00:00 2001 From: Ievgenii Meshcheriakov Date: Tue, 10 Aug 2021 14:30:10 +0200 Subject: [PATCH] QUrl: Fix handling of invalid sequences starting with xn-- Return ASCII sequences that start with xn-- but fail Punycode decoding as is when converting URLs to Unicode. This is consistent with handling of sequences that do decode successfully but fail other validity checks. This fixes one test in tst_qurlinternal. Task-number: QTBUG-95689 Pick-to: 6.2 Change-Id: I63d7197f25102c96f5dc21d9fecec5e015c531cb Reviewed-by: Thiago Macieira --- src/corelib/io/qurlidna.cpp | 9 ++++++--- tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qurlidna.cpp b/src/corelib/io/qurlidna.cpp index c1a5220dbbd..5621fa83a31 100644 --- a/src/corelib/io/qurlidna.cpp +++ b/src/corelib/io/qurlidna.cpp @@ -2596,10 +2596,13 @@ QString qt_ACE_do(QStringView domain, AceOperation op, AceLeadingDot dot) // We use resize()+memcpy() here because we're overwriting the data we've copied bool appended = false; if (isIdnEnabled) { + // The decoding step can fail here if the original domain name contained + // labels that start with "xn--" but don't contain valid Punycode. Even + // if the label was decoded correctly, it may still break some IDNA rules. + // In either case the original ASCII label should be used instead of + // the result returned by the decoder. QString tmp = qt_punycodeDecoder(aceForm); - if (tmp.isEmpty()) - return QString(); // shouldn't happen, since we've just punycode-encoded it - if (qt_check_nameprepped_std3(tmp)) { + if (!tmp.isEmpty() && qt_check_nameprepped_std3(tmp)) { result.resize(prevLen + tmp.size()); memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar)); appended = true; diff --git a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp index 6a55295f4be..1de7c648d79 100644 --- a/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp +++ b/tests/auto/corelib/io/qurlinternal/tst_qurlinternal.cpp @@ -705,7 +705,6 @@ void tst_QUrlInternal::ace_testsuite() QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); QEXPECT_FAIL("punycode-overflow-2", "QTBUG-95689: Missing oweflow check in punycode decoder", Abort); - QEXPECT_FAIL("punycode-overflow-3", "QTBUG-95689: Returns empty string", Abort); if (fromace != ".") QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);