Ensure proper handling of empty-but-present URL components
authorThiago Macieira <thiago.macieira@intel.com>
Wed, 11 Apr 2012 20:55:18 +0000 (17:55 -0300)
committerQt by Nokia <qt-info@nokia.com>
Thu, 12 Apr 2012 21:01:37 +0000 (23:01 +0200)
The new QUrl is able to distinguish a URL component that is empty from
one that is absent. The previous one already had that capability for
the port, fragment and query, and the new one extends that to the username,
password and path. The path did not need this handling because its
delimiter from the authority it part of the path.

For example, a URL with no username is one where it's set to QString()
(null). A URL like "http://:kde@kde.org" is understood as an
empty-but-present username, for which toString(RemovePassword) will
return "http://@kde.org", keeping the empty-but-present username.

Change-Id: I2d97a7656f3f1099e3cf400b199e68e4c480d924
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
src/corelib/io/qurl.cpp
tests/auto/corelib/io/qurl/tst_qurl.cpp

index 1cf7e30..fbc8d76 100644 (file)
@@ -480,7 +480,9 @@ inline void QUrlPrivate::appendAuthority(QString &appendTo, QUrl::FormattingOpti
 {
     if ((options & QUrl::RemoveUserInfo) != QUrl::RemoveUserInfo) {
         appendUserInfo(appendTo, options, appendingTo);
-        if (hasUserInfo())
+
+        // add '@' only if we added anything
+        if (hasUserName() || (hasPassword() && (options & QUrl::RemovePassword) == 0))
             appendTo += QLatin1Char('@');
     }
     appendHost(appendTo, options);
index e069ee7..f9fbb8c 100644 (file)
@@ -808,10 +808,21 @@ void tst_QUrl::toString_data()
                         << uint(QUrl::RemovePassword)
                         << QString::fromLatin1("http://ole@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
 
+    // show that QUrl keeps the empty-but-present username if you remove the password
+    // see data3-bis for another case
+    QTest::newRow("data2-bis") << QString::fromLatin1("http://:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
+                        << uint(QUrl::RemovePassword)
+                        << QString::fromLatin1("http://@www.troll.no:9090/index.html?ole=semann&gud=hei#top");
+
     QTest::newRow("data3") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
                         << uint(QUrl::RemoveUserInfo)
                         << QString::fromLatin1("http://www.troll.no:9090/index.html?ole=semann&gud=hei#top");
 
+    // show that QUrl keeps the empty-but-preset hostname if you remove the userinfo
+    QTest::newRow("data3-bis") << QString::fromLatin1("http://ole:password@/index.html?ole=semann&gud=hei#top")
+                        << uint(QUrl::RemoveUserInfo)
+                        << QString::fromLatin1("http:///index.html?ole=semann&gud=hei#top");
+
     QTest::newRow("data4") << QString::fromLatin1("http://ole:password@www.troll.no:9090/index.html?ole=semann&gud=hei#top")
                         << uint(QUrl::RemovePort)
                         << QString::fromLatin1("http://ole:password@www.troll.no/index.html?ole=semann&gud=hei#top");
@@ -926,20 +937,26 @@ void tst_QUrl::toString_constructed_data()
     QTest::addColumn<QString>("fragment");
     QTest::addColumn<QString>("asString");
     QTest::addColumn<QByteArray>("asEncoded");
+    QTest::addColumn<uint>("options");
 
     QString n("");
 
     QTest::newRow("data1") << n << n << n << QString::fromLatin1("qt.nokia.com") << -1 << QString::fromLatin1("index.html")
                         << QByteArray() << n << QString::fromLatin1("//qt.nokia.com/index.html")
-                        << QByteArray("//qt.nokia.com/index.html");
+                        << QByteArray("//qt.nokia.com/index.html") << 0u;
     QTest::newRow("data2") << QString::fromLatin1("file") << n << n << n << -1 << QString::fromLatin1("/root") << QByteArray()
-                        << n << QString::fromLatin1("file:///root") << QByteArray("file:///root");
+                        << n << QString::fromLatin1("file:///root") << QByteArray("file:///root") << 0u;
     QTest::newRow("userAndPass") << QString::fromLatin1("http") << QString::fromLatin1("dfaure") << QString::fromLatin1("kde")
                         << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
-                        << QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/");
+                        << QString::fromLatin1("http://dfaure:kde@kde.org:443/") << QByteArray("http://dfaure:kde@kde.org:443/")
+                        << 0u;
     QTest::newRow("PassWithoutUser") << QString::fromLatin1("http") << n << QString::fromLatin1("kde")
                         << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
-                        << QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/");
+                        << QString::fromLatin1("http://:kde@kde.org:443/") << QByteArray("http://:kde@kde.org:443/") << 0u;
+    QTest::newRow("PassWithoutUser-RemovePassword") << QString::fromLatin1("http") << n << QString::fromLatin1("kde")
+                        << "kde.org" << 443 << QString::fromLatin1("/") << QByteArray() << n
+                        << QString::fromLatin1("http://kde.org:443/") << QByteArray("http://kde.org:443/")
+                        << uint(QUrl::RemovePassword);
 }
 
 void tst_QUrl::toString_constructed()
@@ -954,6 +971,7 @@ void tst_QUrl::toString_constructed()
     QFETCH(QString, fragment);
     QFETCH(QString, asString);
     QFETCH(QByteArray, asEncoded);
+    QFETCH(uint, options);
 
     QUrl url;
     if (!scheme.isEmpty())
@@ -974,9 +992,11 @@ void tst_QUrl::toString_constructed()
         url.setFragment(fragment);
 
     QVERIFY(url.isValid());
-    QCOMPARE(url.toString(), asString);
-    QCOMPARE(QString::fromLatin1(url.toEncoded()), QString::fromLatin1(asEncoded)); // readable in case of differences
-    QCOMPARE(url.toEncoded(), asEncoded);
+
+    QUrl::FormattingOptions formattingOptions(options);
+    QCOMPARE(url.toString(formattingOptions), asString);
+    QCOMPARE(QString::fromLatin1(url.toEncoded(formattingOptions)), QString::fromLatin1(asEncoded)); // readable in case of differences
+    QCOMPARE(url.toEncoded(formattingOptions), asEncoded);
 }