From aba336c2b4ad8926dc8a000718bbb7f8a6d5a72d Mon Sep 17 00:00:00 2001 From: David Faure Date: Sun, 8 Sep 2013 15:16:26 +0200 Subject: [PATCH] QUrl: ensure that setPath("//path") doesn't lead to scheme://path which would interpret 'path' as a hostname. The check is in the public setPath so that the internal one can still support parsing URLs such as ftp://ftp.example.com//path. [ChangeLog][Important Behavior Changes][QUrl and QUrlQuery]QUrl now normalizes the path given in setPath, removing ./ and ../ and duplicate slashes. Change-Id: I05ccd8a1d813de45e460384239c059418a8e6a08 Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 4 +++- tests/auto/corelib/io/qurl/tst_qurl.cpp | 8 ++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 9f9653ea94..1854ea9487 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2386,6 +2386,7 @@ void QUrl::setPath(const QString &path, ParsingMode mode) mode = TolerantMode; } + data = qt_normalizePathSegments(data, false); d->setPath(data, 0, data.length()); // optimized out, since there is no path delimiter @@ -3251,9 +3252,10 @@ QUrl QUrl::adjusted(QUrl::FormattingOptions options) const if (options & RemovePath) { that.setPath(QString()); } else if (options & (StripTrailingSlash | RemoveFilename | NormalizePathSegments)) { + that.detach(); QString path; d->appendPath(path, options | FullyEncoded, QUrlPrivate::Path); - that.setPath(path, TolerantMode); + that.d->setPath(path, 0, path.length()); } return that; } diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 2fc0ea5c2a..e2fa0d3b47 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -3373,6 +3373,12 @@ void tst_QUrl::setComponents_data() QTest::newRow("path-%3A-before-slash") << QUrl() << int(Path) << "c%3A/" << Tolerant << true << PrettyDecoded << "c%3A/" << "c%3A/"; + QTest::newRow("path-doubleslash") << QUrl("trash:/") + << int(Path) << "//path" << Tolerant << true + << PrettyDecoded << "/path" << "trash:/path"; + QTest::newRow("path-withdotdot") << QUrl("file:///tmp") + << int(Path) << "//tmp/..///root/." << Tolerant << true + << PrettyDecoded << "/root" << "file:///root"; // the other fields can be present and be empty // that is, their delimiters would be present, but there would be nothing to one side @@ -3642,6 +3648,8 @@ void tst_QUrl::setComponents() if (isValid) { QFETCH(QString, toString); QCOMPARE(copy.toString(), toString); + // Check round-tripping + QCOMPARE(QUrl(copy.toString()).toString(), toString); } else { QVERIFY(copy.toString().isEmpty()); }