summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qurl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qurl.cpp')
-rw-r--r--src/corelib/io/qurl.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 44160b3d8b..aed1be2ffb 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -279,6 +279,12 @@ static inline char toHex(quint8 c)
return c > 9 ? c - 10 + 'A' : c + '0';
}
+static inline quint8 fromHex(quint8 c)
+{
+ c |= 0x20;
+ return c >= 'a' ? c - 'a' + 10 : c - '0';
+}
+
static inline QString ftpScheme()
{
return QStringLiteral("ftp");
@@ -2495,6 +2501,9 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
returned value in the form found on SMB networks (for example,
"//servername/path/to/file.txt").
+ Note: if the path component of this URL contains a non-UTF-8 binary
+ sequence (such as %80), the behaviour of this function is undefined.
+
\sa fromLocalFile(), isLocalFile()
*/
QString QUrl::toLocalFile() const
@@ -2519,6 +2528,20 @@ QString QUrl::toLocalFile() const
#endif
}
+ // check if we need to do one more decoding pass
+ int pct = tmp.indexOf(QLatin1Char('%'));
+ while (pct != -1) {
+ Q_ASSERT(tmp.size() >= pct + 2);
+ ushort char1 = tmp.at(pct + 1).unicode();
+ ushort char2 = tmp.at(pct + 2).unicode();
+
+ Q_ASSERT(isHex(char1) && char1 < 0x80u);
+ Q_ASSERT(isHex(char2) && char2 < 0x80u);
+ tmp.replace(pct, 3, QChar(fromHex(char1) << 4 | fromHex(char2)));
+
+ // next iteration
+ pct = tmp.indexOf(QLatin1Char('%'), pct + 1);
+ }
return tmp;
}