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 <thiago.macieira@intel.com>
This commit is contained in:
Ievgenii Meshcheriakov 2021-08-10 14:30:10 +02:00 committed by Thiago Macieira
parent 22bf383519
commit 2b4ffe914f
2 changed files with 6 additions and 4 deletions

View File

@ -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 // We use resize()+memcpy() here because we're overwriting the data we've copied
bool appended = false; bool appended = false;
if (isIdnEnabled) { 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); QString tmp = qt_punycodeDecoder(aceForm);
if (tmp.isEmpty()) if (!tmp.isEmpty() && qt_check_nameprepped_std3(tmp)) {
return QString(); // shouldn't happen, since we've just punycode-encoded it
if (qt_check_nameprepped_std3(tmp)) {
result.resize(prevLen + tmp.size()); result.resize(prevLen + tmp.size());
memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar)); memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar));
appended = true; appended = true;

View File

@ -705,7 +705,6 @@ void tst_QUrlInternal::ace_testsuite()
QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix);
QEXPECT_FAIL("punycode-overflow-2", "QTBUG-95689: Missing oweflow check in punycode decoder", QEXPECT_FAIL("punycode-overflow-2", "QTBUG-95689: Missing oweflow check in punycode decoder",
Abort); Abort);
QEXPECT_FAIL("punycode-overflow-3", "QTBUG-95689: Returns empty string", Abort);
if (fromace != ".") if (fromace != ".")
QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix);
QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix);