Commit c5dbb7c5 authored by Ahmad Samir's avatar Ahmad Samir
Browse files

KFileWidget: allow files that begin with a ':' to be selected

The issue was that a ':' at the beginning denotes a Qt Resource and in that
case QDir::isAbsolutePath() would return true. The bug is fixed by guarding
against that condition in slotOk().

Also guard other QDir::isAbsolutePath() usage the same way.

Since this logic will be used in various places use a helper function,
isAbsoluteLocalPath() (thanks to dfaure for coming up with that name),
in pathhelpers_p.h.

Extend the unit tests.

BUG: 322837
FIXED-IN: 5.78
parent 89ed4f29
......@@ -604,6 +604,12 @@ private Q_SLOTS:
<< QStringList{"some#thing"}
<< QString("some#thing");
// Filenames beginning with ':'; QDir::isAbsolutePath() always returns true
// in that case, #322837
QTest::newRow("file-beginning-with-colon") << QStringList{":test2"} << QString{":test2"};
QTest::newRow("multiple-files-beginning-with-colon") << QStringList{":test space", ":test2"}
<< QString{"\":test space\" \":test2\""};
}
void testTokenize()
......@@ -615,20 +621,23 @@ private Q_SLOTS:
QFETCH(QString, expectedCurrentText);
QTemporaryDir tempDir;
const QUrl dirUrl = QUrl::fromLocalFile(tempDir.path());
const QString tempDirPath = tempDir.path();
const QUrl tempDirUrl = QUrl::fromLocalFile(tempDirPath);
QList<QUrl> fileUrls;
for (const auto& fileName : fileNames) {
fileUrls.append(QUrl::fromLocalFile(tempDir.filePath(fileName)));
qCDebug(KIO_KFILEWIDGETS_FW) << fileName << " => " << QUrl::fromLocalFile(tempDir.filePath(fileName));
for (const auto &fileName : fileNames) {
const QString filePath = tempDirPath + QLatin1Char('/') + fileName;
const QUrl localUrl = QUrl::fromLocalFile(filePath);
fileUrls.append(localUrl);
qCDebug(KIO_KFILEWIDGETS_FW) << fileName << " => " << localUrl;
}
KFileWidget fw(dirUrl);
KFileWidget fw(tempDirUrl);
fw.setOperationMode(KFileWidget::Opening);
fw.setMode(KFile::Files);
fw.setSelectedUrls(fileUrls);
// Verify the expected populated name.
QCOMPARE(fw.baseUrl().adjusted(QUrl::StripTrailingSlash), dirUrl);
QCOMPARE(fw.baseUrl().adjusted(QUrl::StripTrailingSlash), tempDirUrl);
QCOMPARE(fw.locationEdit()->currentText(), expectedCurrentText);
// QFileDialog ends up calling KDEPlatformFileDialog::selectedFiles()
......
......@@ -13,7 +13,7 @@
*/
#include "kfilewidget.h"
#include "../pathhelpers_p.h"
#include "../pathhelpers_p.h" // concatPaths() and isAbsoluteLocalPath()
#include "kfileplacesview.h"
#include "kfileplacesmodel.h"
......@@ -338,7 +338,7 @@ static bool containsProtocolSection(const QString &string)
// without the http-prepending that QUrl::fromUserInput does.
static QUrl urlFromString(const QString& str)
{
if (QDir::isAbsolutePath(str)) {
if (isAbsoluteLocalPath(str)) {
return QUrl::fromLocalFile(str);
}
QUrl url(str);
......@@ -765,7 +765,7 @@ QUrl KFileWidgetPrivate::getCompleteUrl(const QString &_url) const
const QString url = KShell::tildeExpand(_url);
QUrl u;
if (QDir::isAbsolutePath(url)) {
if (isAbsoluteLocalPath(url)) {
u = QUrl::fromLocalFile(url);
} else {
QUrl relativeUrlTest(ops->url());
......@@ -932,9 +932,8 @@ void KFileWidget::slotOk()
} else if (!locationEditCurrentTextList.isEmpty()) {
// if we are on file or files mode, and we have an absolute url written by
// the user, convert it to relative
if (!locationEditCurrentText.isEmpty() && !(mode & KFile::Directory) &&
(QDir::isAbsolutePath(locationEditCurrentText) ||
containsProtocolSection(locationEditCurrentText))) {
if (!locationEditCurrentText.isEmpty() && !(mode & KFile::Directory)
&& (isAbsoluteLocalPath(locationEditCurrentText) || containsProtocolSection(locationEditCurrentText))) {
QString fileName;
QUrl url = urlFromString(locationEditCurrentText);
......
......@@ -8,6 +8,7 @@
#ifndef KIO_PATHHELPERS_P_H
#define KIO_PATHHELPERS_P_H
#include <QDir>
#include <QString>
inline
......@@ -24,4 +25,13 @@ QString concatPaths(const QString &path1, const QString &path2)
}
}
inline
bool isAbsoluteLocalPath(const QString &path)
{
// QDir::isAbsolutePath() will return true if "path" starts with ':', the latter denotes a
// Qt Resource (qrc).
// "Local" as in on local disk not in memory (qrc)
return !path.startsWith(QLatin1Char(':')) && QDir::isAbsolutePath(path);
}
#endif // KIO_PATHHELPERS_P_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment