diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2012-04-23 17:16:31 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-26 03:15:22 +0200 |
commit | f6aef23ff162d9849f5be1036c9f45c2ee506d21 (patch) | |
tree | dfa65e69cfdd009a9072d554fd54391fc1420a87 /src | |
parent | f9048b3465d163a3c4e12fe6b9261d42a996b314 (diff) |
Ensure that QUrl::{to,from}LocalPath encode/decode properly
Unlike path(), toLocalFile() isn't reporting a URL component, so it
should decode the percent-encoded characters fully. This extra
decoding pass is meant to catch %00 to %1F, %7F and %25 (the percent
sign itself).
It also catches %80 to %FF, which aren't decoded because they don't
form UTF-8 sequences. That means QUrl::toLocalFile() has undefined
behaviour if the path contained non-UTF8 sequences.
Task-number: QTBUG-25459
Change-Id: Iab5a0ba6afcfc4510e297984f2ffc208cedd752b
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/io/qurl.cpp | 23 |
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; } |