Utils: Use simplistic percentencoding for host parts of FilePath

Host parts with true slashes (as possible currently for docker ids
using the repo:tag style) breaks parsing in FilePath::fromString.

This provides a means to use such names nevertheless.

Task-number: QTCREATORBUG-26856
Change-Id: Iba3568c5708fe495d0dd657540f30a2519e7f45f
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
hjk
2022-02-24 16:00:58 +01:00
parent f334bd422e
commit 4ca780ccb3
2 changed files with 19 additions and 5 deletions

View File

@@ -454,14 +454,21 @@ FilePath FilePath::fromUrl(const QUrl &url)
return fn; return fn;
} }
static QString hostEncoded(QString host)
{
host.replace('%', "%25");
host.replace('/', "%2f");
return host;
}
/// \returns a QString for passing on to QString based APIs /// \returns a QString for passing on to QString based APIs
QString FilePath::toString() const QString FilePath::toString() const
{ {
if (m_scheme.isEmpty()) if (m_scheme.isEmpty())
return m_data; return m_data;
if (m_data.startsWith('/')) if (m_data.startsWith('/'))
return m_scheme + "://" + m_host + m_data; return m_scheme + "://" + hostEncoded(m_host) + m_data;
return m_scheme + "://" + m_host + "/./" + m_data; return m_scheme + "://" + hostEncoded(m_host) + "/./" + m_data;
} }
QUrl FilePath::toUrl() const QUrl FilePath::toUrl() const
@@ -595,7 +602,6 @@ void FilePath::setScheme(const QString &scheme)
void FilePath::setHost(const QString &host) void FilePath::setHost(const QString &host)
{ {
QTC_CHECK(!host.contains('/'));
m_host = host; m_host = host;
} }
@@ -943,6 +949,8 @@ void FilePath::setFromString(const QString &filename)
m_data = filename.mid(pos1); m_data = filename.mid(pos1);
} else { } else {
m_host = filename.mid(pos1, pos2 - pos1); m_host = filename.mid(pos1, pos2 - pos1);
m_host.replace("%2f", "/");
m_host.replace("%25", "%");
m_data = filename.mid(pos2); m_data = filename.mid(pos2);
} }
if (m_data.startsWith("/./")) if (m_data.startsWith("/./"))

View File

@@ -105,7 +105,6 @@ public:
bool endsWith(const QString &s) const; bool endsWith(const QString &s) const;
bool exists() const; bool exists() const;
bool needsDevice() const;
FilePath parentDir() const; FilePath parentDir() const;
bool isChildOf(const FilePath &s) const; bool isChildOf(const FilePath &s) const;
@@ -191,6 +190,13 @@ public:
qint64 maxSize = -1, qint64 offset = 0) const; qint64 maxSize = -1, qint64 offset = 0) const;
void asyncWriteFileContents(const Continuation<bool> &cont, const QByteArray &data) const; void asyncWriteFileContents(const Continuation<bool> &cont, const QByteArray &data) const;
// Prefer not to use
// Using needsDevice() in "user" code is likely to result in code that
// makes a local/remote distinction which should be avoided in general.
// There are usually other means available. E.g. distinguishing based
// on FilePath::osType().
bool needsDevice() const;
// Deprecated. // Deprecated.
[[nodiscard]] static FilePath fromFileInfo(const QFileInfo &info); // Avoid. [[nodiscard]] static FilePath fromFileInfo(const QFileInfo &info); // Avoid.
[[nodiscard]] QFileInfo toFileInfo() const; // Avoid. [[nodiscard]] QFileInfo toFileInfo() const; // Avoid.
@@ -205,7 +211,7 @@ private:
[[nodiscard]] QString mapToDevicePath() const; [[nodiscard]] QString mapToDevicePath() const;
QString m_scheme; QString m_scheme;
QString m_host; QString m_host; // May contain raw slashes.
QString m_data; QString m_data;
}; };