QUrl: Always lowercase the scheme
authorThiago Macieira <thiago.macieira@intel.com>
Wed, 19 Oct 2011 18:31:46 +0000 (20:31 +0200)
committerQt by Nokia <qt-info@nokia.com>
Thu, 29 Mar 2012 23:19:59 +0000 (01:19 +0200)
Change-Id: I8d467014d22384f1be15fdd746e20b1153a82a4e
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
src/corelib/io/qurl.cpp
tests/auto/corelib/io/qurl/tst_qurl.cpp

index 51937ee..b8ab9df 100644 (file)
@@ -514,6 +514,7 @@ bool QUrlPrivate::setScheme(const QString &value, int len, bool decoded)
     //    scheme        = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
     // but we need to decode any percent-encoding sequences that fall on
     // those characters
+    // we also lowercase the scheme
 
     scheme.clear();
     sectionIsPresent |= Scheme;
@@ -522,12 +523,15 @@ bool QUrlPrivate::setScheme(const QString &value, int len, bool decoded)
         return false;
 
     // validate it:
+    int needsLowercasing = -1;
     const ushort *p = reinterpret_cast<const ushort *>(value.constData());
     for (int i = 0; i < len; ++i) {
         if (p[i] >= 'a' && p[i] <= 'z')
             continue;
-        if (p[i] >= 'A' && p[i] <= 'Z')
+        if (p[i] >= 'A' && p[i] <= 'Z') {
+            needsLowercasing = i;
             continue;
+        }
         if (p[i] >= '0' && p[i] <= '9' && i > 0)
             continue;
         if (p[i] == '+' || p[i] == '-' || p[i] == '.')
@@ -551,6 +555,16 @@ bool QUrlPrivate::setScheme(const QString &value, int len, bool decoded)
 
     scheme = value.left(len);
     sectionHasError &= ~Scheme;
+
+    if (needsLowercasing != -1) {
+        // schemes are ASCII only, so we don't need the full Unicode toLower
+        QChar *schemeData = scheme.data(); // force detaching here
+        for (int i = needsLowercasing; i >= 0; --i) {
+            register ushort c = schemeData[i].unicode();
+            if (c >= 'A' && c <= 'Z')
+                schemeData[i] = c + 0x20;
+        }
+    }
     return true;
 }
 
@@ -2308,7 +2322,7 @@ bool QUrl::isLocalFile() const
 {
     if (!d) return false;
 
-    if (d->scheme.compare(fileScheme(), Qt::CaseInsensitive) != 0)
+    if (d->scheme != fileScheme())
         return false;   // not file
     return true;
 }
index 1c34d8a..680cc3b 100644 (file)
@@ -155,6 +155,7 @@ private slots:
     void toEncodedNotUsingUninitializedPath();
     void emptyAuthorityRemovesExistingAuthority();
     void acceptEmptyAuthoritySegments();
+    void lowercasesScheme();
 };
 
 // Testing get/set functions
@@ -320,9 +321,9 @@ void tst_QUrl::setUrl()
     }
 
     {
-        QUrl url("hTTp://www.foo.bar:80");
+        QUrl url("http://www.foo.bar:80");
         QVERIFY(url.isValid());
-        QCOMPARE(url.scheme(), QString::fromLatin1("hTTp"));
+        QCOMPARE(url.scheme(), QString::fromLatin1("http"));
         QCOMPARE(url.path(), QString());
         QVERIFY(url.encodedQuery().isEmpty());
         QVERIFY(url.userInfo().isEmpty());
@@ -330,12 +331,12 @@ void tst_QUrl::setUrl()
         QCOMPARE(url.host(), QString::fromLatin1("www.foo.bar"));
         QCOMPARE(url.authority(), QString::fromLatin1("www.foo.bar:80"));
         QCOMPARE(url.port(), 80);
-        QCOMPARE(url.toString(), QString::fromLatin1("hTTp://www.foo.bar:80"));
-        QCOMPARE(url.toDisplayString(), QString::fromLatin1("hTTp://www.foo.bar:80"));
-        QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("hTTp://www.foo.bar:80"));
+        QCOMPARE(url.toString(), QString::fromLatin1("http://www.foo.bar:80"));
+        QCOMPARE(url.toDisplayString(), QString::fromLatin1("http://www.foo.bar:80"));
+        QCOMPARE(url.toDisplayString(QUrl::PreferLocalFile), QString::fromLatin1("http://www.foo.bar:80"));
 
         QUrl url2("//www1.foo.bar");
-        QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("hTTp://www1.foo.bar"));
+        QCOMPARE(url.resolved(url2).toString(), QString::fromLatin1("http://www1.foo.bar"));
     }
 
     {
@@ -2481,5 +2482,12 @@ void tst_QUrl::effectiveTLDs()
     QCOMPARE(domain.topLevelDomain(), TLD);
 }
 
+void tst_QUrl::lowercasesScheme()
+{
+    QUrl url;
+    url.setScheme("HELLO");
+    QCOMPARE(url.scheme(), QString("hello"));
+}
+
 QTEST_MAIN(tst_QUrl)
 #include "tst_qurl.moc"