From 76c63936d3d3c937960108da88a56394a0ac70b5 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 28 Feb 2023 15:28:20 +0100 Subject: [PATCH] macOS: Send a filename QFileOpenEvent if invalid URL, deprecate openFile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the string we receive from the system doesn't parse into a valid QUrl (because QUrl requires a valid IDN), then we shouldn't send the QFileOpenEvent based on that invalid QUrl, but instead pass the string through as the file name. The file name is anyway not guaranteed to be path to a file that can be opened, as per the existence of QFileOpenEvent::open and the repective documentation stating: "some files cannot be opened by name, but require specific information stored in this event." However, that API is not useful at all, the implementation just opens the passed-in QFile, using the stored file name. There's no way to override this, and QFileOpenEvent is a locked class with all data stored inline. So we can't even redirect to a platform-implementation. Deprecate that function. Applications should interpret the string returned by file(), which might not be a path to a local file. Fixes: QTBUG-98384 Change-Id: Iff75489de9d7c5fc034f44c0bda4963b2efb1925 Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qevent.cpp | 9 +++++++-- src/gui/kernel/qevent.h | 3 +++ .../platforms/cocoa/qcocoaapplicationdelegate.mm | 11 ++++++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 9792490257e..8e871d76942 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3625,19 +3625,23 @@ Q_IMPL_EVENT_COMMON(QFileOpenEvent) /*! \fn QString QFileOpenEvent::file() const - Returns the file that is being opened. + Returns the name of the file that the application should open. + + This is not guaranteed to be the path to a local file. */ /*! \fn QUrl QFileOpenEvent::url() const - Returns the url that is being opened. + Returns the url that the application should open. \since 4.6 */ +#if QT_DEPRECATED_SINCE(6, 6) /*! \fn bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const + \deprecated [6.6] interpret the string returned by file() Opens a QFile on the \a file referenced by this event in the mode specified by \a flags. Returns \c true if successful; otherwise returns \c false. @@ -3652,6 +3656,7 @@ bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const file.setFileName(m_file); return file.open(flags); } +#endif #ifndef QT_NO_TOOLBAR /*! diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index a3fd09d9a4c..900524d2188 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -852,7 +852,10 @@ public: inline QString file() const { return m_file; } QUrl url() const { return m_url; } +#if QT_DEPRECATED_SINCE(6, 6) + QT_DEPRECATED_VERSION_X_6_6("Interpret the string returned by file()") bool openFile(QFile &file, QIODevice::OpenMode flags) const; +#endif private: QString m_file; QUrl m_url; diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index b13ec3bee88..f2b7bde8f0d 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -318,7 +318,16 @@ QT_USE_NAMESPACE { Q_UNUSED(replyEvent); NSString *urlString = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; - QWindowSystemInterface::handleFileOpenEvent(QUrl(QString::fromNSString(urlString))); + // The string we get from the requesting application might not necessarily meet + // QUrl's requirement for a IDN-compliant host. So if we can't parse into a QUrl, + // then we pass the string on to the application as the name of a file (and + // QFileOpenEvent::file is not guaranteed to be the path to a local, open'able + // file anyway). + const QString qurlString = QString::fromNSString(urlString); + if (const QUrl url(qurlString); url.isValid()) + QWindowSystemInterface::handleFileOpenEvent(url); + else + QWindowSystemInterface::handleFileOpenEvent(qurlString); } @end