summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qdir.cpp
diff options
context:
space:
mode:
authorAhmad Samir <a.samirh78@gmail.com>2024-09-19 14:39:20 +0300
committerAhmad Samir <a.samirh78@gmail.com>2024-10-04 20:08:35 +0300
commitec894d694506fcce75fc9643f08dfb1c79f64c8b (patch)
tree5126933088ed0a60b83ea3095e742d2172522296 /src/corelib/io/qdir.cpp
parentdc1d3abd7e852829b9bc81c1ba9565f40147402d (diff)
QDir: change qt_normalizePathSegments to preserve trailing '/'s
... for local URLs too. For example normalizing "/Users/sam/troll/qt4.0/.." by following the alogrithm at https://www.ietf.org/rfc/rfc3986.html#section-5.2.4: - replace "/.." with a "/" in the input buffer, then remove the previous path segment from the output buffer up to, and including, the previous "/" - next iteration will find the input buffer starting with a "/" which is moved to the output buffer; the final result would be: "/Users/sam/troll/" Remove the KeepLocalTrailingSlash enumerator, it's become redundant with this change. De-duplicate a row in tst_QDir. [ChangeLog][Important Behavior Change] Aligned how QDir and QUrl normalize paths with respect to preserving a trailing slash. That is, QDir::cleanPath("/b/.") and QUrl("file:///b/.).toString(QUrl::NormalizePathSegments) will return "/b/" and "file:///b/" respectively. For more details see: https://www.ietf.org/rfc/rfc3986.html#section-5.2.4 Task-number: QTBUG-128940 Change-Id: Id5a4bdab14e7312a60b1b54de07e5d9f3e8aa40a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io/qdir.cpp')
-rw-r--r--src/corelib/io/qdir.cpp33
1 files changed, 7 insertions, 26 deletions
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index f10e1569473..a7e12eaae35 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -2223,16 +2223,12 @@ bool QDir::match(const QString &filter, const QString &fileName)
"a/b/" and "a/b//../.." becomes "a/"), which matches the behavior
observed in web browsers.
- However, QUrl also uses local path mode for local URLs; with one exception:
- Even in local mode we leave one trailing slash for paths ending in "/." if
- the KeepLocalTrailingSlash flag is given. This reflects how QUrl needs to
- treat local URLs due to compatibility constraints.
+ As a Qt extension, for local URLs we treat multiple slashes as one slash.
*/
bool qt_normalizePathSegments(QString *path, QDirPrivate::PathNormalizations flags)
{
const bool allowUncPaths = flags.testAnyFlag(QDirPrivate::AllowUncPaths);
const bool isRemote = flags.testAnyFlag(QDirPrivate::RemotePath);
- const bool keepLocalTrailingSlash = flags.testAnyFlags(QDirPrivate::KeepLocalTrailingSlash);
const qsizetype prefixLength = rootLength(*path, allowUncPaths);
// RFC 3986 says: "The input buffer is initialized with the now-appended
@@ -2343,27 +2339,12 @@ bool qt_normalizePathSegments(QString *path, QDirPrivate::PathNormalizations fla
++in; // the one dot
}
- if (out > start) {
- // Always backtrack one slash
- if (out[-1] == u'/' && in != end)
- --out;
-
- if (!isRemote) {
- bool removedAnySlashes = false;
-
- // Backtrack all slashes ...
- while (out > start && out[-1] == u'/') {
- --out;
- removedAnySlashes = true;
- }
-
- // ... except a trailing one if it exists and flag given
- if (removedAnySlashes && keepLocalTrailingSlash && out > start) {
- ++out;
- break;
- }
- }
- }
+ // Not at 'end' yet, prepare for the next loop iteration by backtracking one slash.
+ // E.g.: /a/b/../c >>> /a/b/../c
+ // ^out ^out
+ // the next iteration will copy '/c' to the output buffer >>> /a/c
+ if (in != end && out > start && out[-1] == u'/')
+ --out;
if (out == start) {
// We've reached the root. Make sure we don't turn a relative path
// to absolute or, in the case of local paths that are already