From 1108291e1a2e7de23440c2b36b2fd31010ae3f51 Mon Sep 17 00:00:00 2001 From: Urs Fleisch Date: Tue, 3 May 2016 20:01:01 +0200 Subject: 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ł Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbmime.cpp | 42 +++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 11 deletions(-) (limited to 'src/plugins/platforms/xcb/qxcbmime.cpp') diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index eeac561870..cef2210794 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 - // 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; + } + } } } -- cgit v1.2.3 From f162e29acca99aaab173fb323d112aad9ec6c2b5 Mon Sep 17 00:00:00 2001 From: Urs Fleisch <ufleisch@users.sourceforge.net> Date: Wed, 4 May 2016 19:47:16 +0200 Subject: xcb: Fix dropping URL on Firefox window. When a URL is dropped on a Firefox window, the "text/x-moz-url" data takes precedence over the "text/uri-list". The "text/x-moz-url" is interpreted as UTF16, however, the data from Qt 5 applications is not in the correct format. The code to create correct UTF16 data exists, but it is not called for two reasons: The atomName will never be "text/x-moz-url" because it is changed to "text/uri-list" by mimeAtomToString() and the InternalMimeData::hasFormatHelper() case is already handled above and the else part will never be considered. This patch fixes the check and brings it into the right order. Task-number: QTBUG-49947 Change-Id: I5ebd31914cc6c1417c513c1ff09e0e858a16915d Reviewed-by: Dmitry Shachnev <mitya57@gmail.com> Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com> --- src/plugins/platforms/xcb/qxcbmime.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'src/plugins/platforms/xcb/qxcbmime.cpp') diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp index cef2210794..7fea0688cc 100644 --- a/src/plugins/platforms/xcb/qxcbmime.cpp +++ b/src/plugins/platforms/xcb/qxcbmime.cpp @@ -111,17 +111,18 @@ bool QXcbMime::mimeDataForAtom(QXcbConnection *connection, xcb_atom_t a, QMimeDa QString atomName = mimeAtomToString(connection, a); if (QInternalMimeData::hasFormatHelper(atomName, mimeData)) { *data = QInternalMimeData::renderDataHelper(atomName, mimeData); - if (atomName == QLatin1String("application/x-color")) + // mimeAtomToString() converts "text/x-moz-url" to "text/uri-list", + // so QXcbConnection::atomName() has to be used. + if (atomName == QLatin1String("text/uri-list") + && connection->atomName(a) == "text/x-moz-url") { + const QByteArray uri = data->split('\n').first(); + QString mozUri = QString::fromLatin1(uri, uri.size()); + mozUri += QLatin1Char('\n'); + *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), + mozUri.length() * 2); + } else if (atomName == QLatin1String("application/x-color")) *dataFormat = 16; ret = true; - } else if (atomName == QLatin1String("text/x-moz-url") && - QInternalMimeData::hasFormatHelper(QLatin1String("text/uri-list"), mimeData)) { - QByteArray uri = QInternalMimeData::renderDataHelper( - QLatin1String("text/uri-list"), mimeData).split('\n').first(); - QString mozUri = QString::fromLatin1(uri, uri.size()); - mozUri += QLatin1Char('\n'); - *data = QByteArray(reinterpret_cast<const char *>(mozUri.utf16()), mozUri.length() * 2); - ret = true; } else if ((a == XCB_ATOM_PIXMAP || a == XCB_ATOM_BITMAP) && mimeData->hasImage()) { ret = true; } -- cgit v1.2.3