Blob Blame History Raw
From 1108291e1a2e7de23440c2b36b2fd31010ae3f51 Mon Sep 17 00:00:00 2001
From: Urs Fleisch <ufleisch@users.sourceforge.net>
Date: Tue, 3 May 2016 20:01:01 +0200
Subject: [PATCH 032/178] xcb: Fix drop of text/uri-list and text/html.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

When dropping URLs from Firefox or Chrome, the contents are encoded as
UTF16, but not correctly decoded. Moreover, the special handling of
"text/x-moz-url" drops does not work because this format is converted to
"text/uri-list" before. This fixes the handling for URL list and also
for UTF16 "text/html".

Task-number: QTBUG-47981
Change-Id: I1153f21ede07b2bfe4d104e0fe8bc8487ec5c165
Reviewed-by: Błażej Szczygieł <spaz16@wp.pl>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
---
 src/plugins/platforms/xcb/qxcbmime.cpp | 42 +++++++++++++++++++++++++---------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp
index eeac561..cef2210 100644
--- a/src/plugins/platforms/xcb/qxcbmime.cpp
+++ b/src/plugins/platforms/xcb/qxcbmime.cpp
@@ -182,17 +182,37 @@ QVariant QXcbMime::mimeConvertToFormat(QXcbConnection *connection, xcb_atom_t a,
             a == connection->atom(QXcbAtom::TEXT))
             return QString::fromLatin1(data);
     }
-
-    // special case for uri types
-    if (format == QLatin1String("text/uri-list")) {
-        if (atomName == QLatin1String("text/x-moz-url")) {
-            // we expect this as utf16 <url><space><title>
-            // the first part is a url that should only contain ascci char
-            // so it should be safe to check that the second char is 0
-            // to verify that it is utf16
-            if (data.size() > 1 && data.at(1) == 0)
-                return QString::fromRawData((const QChar *)data.constData(),
-                                data.size() / 2).split(QLatin1Char('\n')).first().toLatin1();
+    // If data contains UTF16 text, convert it to a string.
+    // Firefox uses UTF16 without BOM for text/x-moz-url, "text/html",
+    // Google Chrome uses UTF16 without BOM for "text/x-moz-url",
+    // UTF16 with BOM for "text/html".
+    if ((format == QLatin1String("text/html") || format == QLatin1String("text/uri-list"))
+        && data.size() > 1) {
+        const quint8 byte0 = data.at(0);
+        const quint8 byte1 = data.at(1);
+        if ((byte0 == 0xff && byte1 == 0xfe) || (byte0 == 0xfe && byte1 == 0xff)
+            || (byte0 != 0 && byte1 == 0) || (byte0 == 0 && byte1 != 0)) {
+            const QString str = QString::fromUtf16(
+                  reinterpret_cast<const ushort *>(data.constData()), data.size() / 2);
+            if (!str.isNull()) {
+                if (format == QLatin1String("text/uri-list")) {
+                    const QStringList urls = str.split(QLatin1Char('\n'));
+                    QList<QVariant> list;
+                    foreach (const QString &s, urls) {
+                        const QUrl url(s.trimmed());
+                        if (url.isValid())
+                            list.append(url);
+                    }
+                    // We expect "text/x-moz-url" as <url><space><title>.
+                    // The atomName variable is not used because mimeAtomToString()
+                    // converts "text/x-moz-url" to "text/uri-list".
+                    if (!list.isEmpty() && connection->atomName(a) == "text/x-moz-url")
+                        return list.first();
+                    return list;
+                } else {
+                    return str;
+                }
+            }
         }
     }
 
-- 
2.7.4