diff options
author | Ulf Hermann <[email protected]> | 2024-09-19 08:43:45 +0200 |
---|---|---|
committer | Ulf Hermann <[email protected]> | 2024-09-19 12:39:10 +0200 |
commit | f7c06f9292bac6821eeec77ecd238302597d6742 (patch) | |
tree | 6a9268d5e8cce6cdb0b133a623b614b6bd31ac77 | |
parent | 9d3f19585aa92aa6990f3096c16c116ec8c010de (diff) |
Revert "QUrl::resolved: rewrite to fix some corner cases for relative URLs"
This reverts commit d7e24e538f69b08cc2e5b20cc44b3d5345382830.
Reason for revert: Causes a behavior change in QUrl. This re-opens
QTBUG-120396 for 6.7.3.
Task-number: QTBUG-120396
Change-Id: I1e47893caa24ced68c7571a1647a5ba6b85f8553
Reviewed-by: Jani Heikkinen <[email protected]>
-rw-r--r-- | src/corelib/io/qurl.cpp | 132 | ||||
-rw-r--r-- | tests/auto/corelib/io/qurl/tst_qurl.cpp | 123 |
2 files changed, 55 insertions, 200 deletions
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index c149ec22f0b..fdafd070dfd 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -1521,12 +1521,6 @@ inline QString QUrlPrivate::mergePaths(const QString &relativePath) const Removes unnecessary ../ and ./ from the path. Used for normalizing the URL. - - This code has a Qt-specific extension to handle empty path segments (a.k.a. - multiple slashes like "a//b"). We try to keep them wherever possible - because with some protocols they are meaningful, but we still consider them - to be a single directory transition for "." or ".." (e.g., "a/b//c" + - "../" is "a/"). See tst_QUrl::resolved() for the expected behavior. */ static void removeDotsFromPath(QString *path) { @@ -1537,87 +1531,71 @@ static void removeDotsFromPath(QString *path) const QChar *in = out; const QChar *end = out + path->size(); - // We implement a modified algorithm compared to RFC 3986, for efficiency. + // If the input buffer consists only of + // "." or "..", then remove that from the input + // buffer; + if (path->size() == 1 && in[0].unicode() == '.') + ++in; + else if (path->size() == 2 && in[0].unicode() == '.' && in[1].unicode() == '.') + in += 2; + // While the input buffer is not empty, loop: while (in < end) { -#if 0 // to see in the debugger - QStringView output(path->constBegin(), out); - QStringView input(in, end); -#endif - // First, copy any preceding slashes, so we can look at the segment's - // content. - while (in < end && in[0] == u'/') { - *out++ = *in++; - - // Note: we may exit this loop with in == end, in which case we - // *shouldn't* dereference *in. But since we are pointing to a - // detached, non-empty QString, we know there's a u'\0' at the end. - } - // Is this path segment either "." or ".."? - enum { Nothing, Dot, DotDot } type = Nothing; - if (in[0] == u'.') { - if (in + 1 == end || in[1] == u'/') - type = Dot; - else if (in[1] == u'.' && (in + 2 == end || in[2] == u'/')) - type = DotDot; + // otherwise, if the input buffer begins with a prefix of "../" or "./", + // then remove that prefix from the input buffer; + if (path->size() >= 2 && in[0].unicode() == '.' && in[1].unicode() == '/') + in += 2; + else if (path->size() >= 3 && in[0].unicode() == '.' + && in[1].unicode() == '.' && in[2].unicode() == '/') + in += 3; + + // otherwise, if the input buffer begins with a prefix of + // "/./" or "/.", where "." is a complete path segment, + // then replace that prefix with "/" in the input buffer; + if (in <= end - 3 && in[0].unicode() == '/' && in[1].unicode() == '.' + && in[2].unicode() == '/') { + in += 2; + continue; + } else if (in == end - 2 && in[0].unicode() == '/' && in[1].unicode() == '.') { + *out++ = u'/'; + in += 2; + break; } - if (type != Nothing) { - // If it is either, we skip it and remove any preceding slashes (if - // any) from the output. If it is "..", we remove the segment - // before that and its preceding slashes (if any) too. - const QChar *start = path->constBegin(); - if (type == DotDot) { - while (out > start && *--out != u'/') - ; - while (out > start && *--out == u'/') - ; - ++in; // the first dot - } - in += 2; // one dot and either one slash or the terminating null - while (out > start && *--out != u'/') + // otherwise, if the input buffer begins with a prefix + // of "/../" or "/..", where ".." is a complete path + // segment, then replace that prefix with "/" in the + // input buffer and remove the last //segment and its + // preceding "/" (if any) from the output buffer; + if (in <= end - 4 && in[0].unicode() == '/' && in[1].unicode() == '.' + && in[2].unicode() == '.' && in[3].unicode() == '/') { + while (out > path->constData() && (--out)->unicode() != '/') ; - - // And then replace the segment with "/", unless it would make a - // relative path become absolute. - if (out != start) { - // Replacing with a slash won't make the path absolute. - *out++ = u'/'; - } else if (*start == u'/') { - // The path is already absolute. - ++out; - } else { - // The path is relative, so we must skip any follow-on slashes - // to make sure the next iteration of the loop won't copy them, - // which would make the path become absolute. - while (in < end && *in == u'/') - ++in; - } + if (out == path->constData() && out->unicode() != '/') + ++in; + in += 3; continue; + } else if (in == end - 3 && in[0].unicode() == '/' && in[1].unicode() == '.' + && in[2].unicode() == '.') { + while (out > path->constData() && (--out)->unicode() != '/') + ; + if (out->unicode() == '/') + ++out; + in += 3; + break; } - // If it is neither, then we copy this segment. + // otherwise move the first path segment in + // the input buffer to the end of the output + // buffer, including the initial "/" character + // (if any) and any subsequent characters up + // to, but not including, the next "/" + // character or the end of the input buffer. + *out++ = *in++; while (in < end && in->unicode() != '/') *out++ = *in++; } - path->truncate(out - path->constBegin()); -} - -// Authority-less URLs cannot have paths starting with double slashes (see -// QUrlPrivate::validityError). We refuse to turn a valid URL into invalid by -// way of QUrl::resolved(). -static void fixupNonAuthorityPath(QString *path) -{ - if (path->isEmpty() || path->at(0) != u'/') - return; - - // Find the first non-slash character, because its position is equal to the - // number of slashes. We'll remove all but one of them. - qsizetype i = 0; - while (i + 1 < path->size() && path->at(i + 1) == u'/') - ++i; - if (i) - path->remove(0, i); + path->truncate(out - path->constData()); } inline QUrlPrivate::ErrorCode QUrlPrivate::validityError(QString *source, qsizetype *position) const @@ -2797,8 +2775,6 @@ QUrl QUrl::resolved(const QUrl &relative) const t.d->sectionIsPresent &= ~QUrlPrivate::Fragment; removeDotsFromPath(&t.d->path); - if (!t.d->hasAuthority()) - fixupNonAuthorityPath(&t.d->path); #if defined(QURL_DEBUG) qDebug("QUrl(\"%ls\").resolved(\"%ls\") = \"%ls\"", diff --git a/tests/auto/corelib/io/qurl/tst_qurl.cpp b/tests/auto/corelib/io/qurl/tst_qurl.cpp index 7151d6d974e..ec901f8b639 100644 --- a/tests/auto/corelib/io/qurl/tst_qurl.cpp +++ b/tests/auto/corelib/io/qurl/tst_qurl.cpp @@ -831,33 +831,7 @@ void tst_QUrl::resolving_data() QTest::addColumn<QString>("relativeUrl"); QTest::addColumn<QString>("resolvedUrl"); - // boundary cases - QTest::newRow("empty-on-empty") << "http://a" << "" << "http://a"; - QTest::newRow("empty-on-/") << "http://a/" << "" << "http://a/"; - QTest::newRow("empty-on-//") << "http://a//" << "" << "http://a//"; - QTest::newRow("empty-on-/.") << "http://a/." << "" << "http://a/"; - QTest::newRow("empty-on-/./") << "http://a/./" << "" << "http://a/"; - QTest::newRow("empty-on-/..") << "http://a/.." << "" << "http://a/"; - QTest::newRow("empty-on-/../") << "http://a/../" << "" << "http://a/"; - - QTest::newRow("/-on-empty-with-authority") << "http://a" << "/" << "http://a/"; - QTest::newRow(".-on-empty-with-authority") << "http://a" << "." << "http://a/"; - QTest::newRow("./-on-empty-with-authority") << "http://a" << "./" << "http://a/"; - QTest::newRow(".//-on-empty-with-authority") << "http://a" << ".//" << "http://a//"; - QTest::newRow("..-on-empty-with-authority") << "http://a" << ".." << "http://a/"; - QTest::newRow("../-on-empty-with-authority") << "http://a" << "../" << "http://a/"; - QTest::newRow("/-on-empty-no-authority") << "scheme:" << "/" << "scheme:/"; - QTest::newRow(".-on-empty-no-authority") << "scheme:" << "." << "scheme:"; - QTest::newRow("./-on-empty-no-authority") << "scheme:" << "./" << "scheme:"; - QTest::newRow(".//-on-empty-no-authority") << "scheme:" << "./" << "scheme:"; - QTest::newRow("..-on-empty-no-authority") << "scheme:" << ".." << "scheme:"; - QTest::newRow("../-on-empty-no-authority") << "scheme:" << "../" << "scheme:"; - - QTest::newRow("scheme-change") << "http://a" << "https://b" << "https://b"; - QTest::newRow("scheme-change-path") << "http://a/" << "scheme:" << "scheme:"; - // 5.4.1 Normal Examples (http://www.ietf.org/rfc/rfc3986.txt) - // URL paths not ending in / QTest::newRow("g:h") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g:h") << QString::fromLatin1("g:h"); QTest::newRow("g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("g") << QString::fromLatin1("http://a/b/c/g"); QTest::newRow("./g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./g") << QString::fromLatin1("http://a/b/c/g"); @@ -875,62 +849,12 @@ void tst_QUrl::resolving_data() QTest::newRow("[empty]") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("") << QString::fromLatin1("http://a/b/c/d;p?q"); QTest::newRow(".") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(".") << QString::fromLatin1("http://a/b/c/"); QTest::newRow("./") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("./") << QString::fromLatin1("http://a/b/c/"); - QTest::newRow(".//") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1(".//") << QString::fromLatin1("http://a/b/c//"); QTest::newRow("..") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("..") << QString::fromLatin1("http://a/b/"); QTest::newRow("../") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../") << QString::fromLatin1("http://a/b/"); - QTest::newRow("..//") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("..//") << QString::fromLatin1("http://a/b//"); QTest::newRow("../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../g") << QString::fromLatin1("http://a/b/g"); - QTest::newRow("..//g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("..//g") << QString::fromLatin1("http://a/b//g"); QTest::newRow("../..") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../..") << QString::fromLatin1("http://a/"); QTest::newRow("../../") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../") << QString::fromLatin1("http://a/"); - QTest::newRow("../..//") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../..//") << QString::fromLatin1("http://a//"); QTest::newRow("../../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../g") << QString::fromLatin1("http://a/g"); - QTest::newRow("../..//g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../..//g") << QString::fromLatin1("http://a//g"); - - // URL paths ending in / - QTest::newRow("g:h-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g:h") << QString::fromLatin1("g:h"); - QTest::newRow("g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g") << QString::fromLatin1("http://a/b/c/g"); - QTest::newRow("./g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("./g") << QString::fromLatin1("http://a/b/c/g"); - QTest::newRow("g/-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g/") << QString::fromLatin1("http://a/b/c/g/"); - QTest::newRow("/g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("/g") << QString::fromLatin1("http://a/g"); - QTest::newRow("//g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("//g") << QString::fromLatin1("http://g"); - QTest::newRow("?y-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("?y") << QString::fromLatin1("http://a/b/c/;p?y"); - QTest::newRow("g?y-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g?y") << QString::fromLatin1("http://a/b/c/g?y"); - QTest::newRow("#s-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("#s") << QString::fromLatin1("http://a/b/c/;p?q#s"); - QTest::newRow("g#s-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g#s") << QString::fromLatin1("http://a/b/c/g#s"); - QTest::newRow("g?y#s-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g?y#s") << QString::fromLatin1("http://a/b/c/g?y#s"); - QTest::newRow(";x-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1(";x") << QString::fromLatin1("http://a/b/c/;x"); - QTest::newRow("g;x-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g;x") << QString::fromLatin1("http://a/b/c/g;x"); - QTest::newRow("g;x?y#s-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("g;x?y#s") << QString::fromLatin1("http://a/b/c/g;x?y#s"); - QTest::newRow("[empty]-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("") << QString::fromLatin1("http://a/b/c/;p?q"); - QTest::newRow(".-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1(".") << QString::fromLatin1("http://a/b/c/"); - QTest::newRow("./-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("./") << QString::fromLatin1("http://a/b/c/"); - QTest::newRow(".//-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1(".//") << QString::fromLatin1("http://a/b/c//"); - QTest::newRow("..-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("..") << QString::fromLatin1("http://a/b/"); - QTest::newRow("../-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("../") << QString::fromLatin1("http://a/b/"); - QTest::newRow("..//-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("..//") << QString::fromLatin1("http://a/b//"); - QTest::newRow("../g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("../g") << QString::fromLatin1("http://a/b/g"); - QTest::newRow("..//g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("..//g") << QString::fromLatin1("http://a/b//g"); - QTest::newRow("../..-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("../..") << QString::fromLatin1("http://a/"); - QTest::newRow("../../-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("../../") << QString::fromLatin1("http://a/"); - QTest::newRow("../..//-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("../..//") << QString::fromLatin1("http://a//"); - QTest::newRow("../../g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("../../g") << QString::fromLatin1("http://a/g"); - QTest::newRow("../..//g-on-/") << QString::fromLatin1("http://a/b/c/;p?q") << QString::fromLatin1("../..//g") << QString::fromLatin1("http://a//g"); - - // URL paths ending in // - QTest::newRow(".-on-//") << "http://a/b/c//" << "." << "http://a/b/c//"; - QTest::newRow("./-on-//") << "http://a/b/c//" << "./" << "http://a/b/c//"; - QTest::newRow(".//-on-//") << "http://a/b/c//" << ".//" << "http://a/b/c///"; // weird but correct - QTest::newRow("..-on-//") << "http://a/b/c//" << ".." << "http://a/b/"; - QTest::newRow("../-on-//") << "http://a/b/c//" << "../" << "http://a/b/"; - QTest::newRow("..//-on-//") << "http://a/b/c//" << "..//" << "http://a/b//"; - QTest::newRow("../g-on-//") << "http://a/b/c//" << "../g" << "http://a/b/g"; - QTest::newRow("..//g-on-//") << "http://a/b/c//" << "..//g" << "http://a/b//g"; - QTest::newRow("../..-on-//") << "http://a/b/c//" << "../.." << "http://a/"; - QTest::newRow("../../-on-//") << "http://a/b/c//" << "../../" << "http://a/"; - QTest::newRow("../..//-on-//") << "http://a/b/c//" << "../..//" << "http://a//"; - QTest::newRow("../../g-on-//") << "http://a/b/c//" << "../../g" << "http://a/g"; - QTest::newRow("../..//g-on-//") << "http://a/b/c//" << "../..//g" << "http://a//g"; // 5.4.2 Abnormal Examples (http://www.ietf.org/rfc/rfc3986.txt) @@ -938,15 +862,8 @@ void tst_QUrl::resolving_data() // relative path ".." segments than there are hierarchical levels in the // base URI's path. Note that the ".." syntax cannot be used to change // the authority component of a URI. - QTest::newRow("../../../") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../") << QString::fromLatin1("http://a/"); - QTest::newRow("../../../..") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../..") << QString::fromLatin1("http://a/"); - QTest::newRow("../../../..//") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../..//") << QString::fromLatin1("http://a//"); - QTest::newRow("../../../../..") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../../..") << QString::fromLatin1("http://a/"); - QTest::newRow("../../../../../") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../../../") << QString::fromLatin1("http://a/"); QTest::newRow("../../../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../g") << QString::fromLatin1("http://a/g"); - QTest::newRow("../../..//g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../..//g") << QString::fromLatin1("http://a//g"); QTest::newRow("../../../../g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../../g") << QString::fromLatin1("http://a/g"); - QTest::newRow("../../../..//g") << QString::fromLatin1("http://a/b/c/d;p?q") << QString::fromLatin1("../../../..//g") << QString::fromLatin1("http://a//g"); // Similarly, parsers must remove the dot-segments "." and ".." when // they are complete components of a path, but not when they are only @@ -992,49 +909,11 @@ void tst_QUrl::resolving_data() QTest::newRow("../a (2)") << QString::fromLatin1("b/a") << QString::fromLatin1("../a") << QString::fromLatin1("a"); QTest::newRow("../a (3)") << QString::fromLatin1("b/c/a") << QString::fromLatin1("../a") << QString::fromLatin1("b/a"); QTest::newRow("../a (4)") << QString::fromLatin1("b") << QString::fromLatin1("/a") << QString::fromLatin1("/a"); - QTest::newRow("relative+.") << "scheme:" << "." << "scheme:"; - QTest::newRow("relative+./") << "scheme:" << "./" << "scheme:"; - QTest::newRow("relative+.//") << "scheme:" << ".//" << "scheme:"; - QTest::newRow("relative+.///") << "scheme:" << ".///" << "scheme:"; - QTest::newRow("relative+./.") << "scheme:" << "./." << "scheme:"; - QTest::newRow("relative+././") << "scheme:" << "././" << "scheme:"; - QTest::newRow("relative+..") << "scheme:" << ".." << "scheme:"; - QTest::newRow("relative+../") << "scheme:" << "../" << "scheme:"; - QTest::newRow("relative+..//") << "scheme:" << "..//" << "scheme:"; - QTest::newRow("relative+..///") << "scheme:" << "..///" << "scheme:"; - QTest::newRow("relative+../.") << "scheme:" << "../." << "scheme:"; - QTest::newRow("relative+.././") << "scheme:" << ".././" << "scheme:"; - QTest::newRow("relative+.././/") << "scheme:" << ".././/" << "scheme:"; - QTest::newRow("relative+.././//") << "scheme:" << ".././//" << "scheme:"; - QTest::newRow("relative+../../../..") << "scheme:b/c/d" << "../../../.." << "scheme:"; - QTest::newRow("relative+../../../../") << "scheme:b/c/d" << "../../../../" << "scheme:"; - QTest::newRow("relative+../../../..//") << "scheme:b/c/d" << "../../../..//" << "scheme:"; - QTest::newRow("relative+../../d/../..") << "scheme:b/c/d" << "../../d/../.." << "scheme:"; - QTest::newRow("relative+../../d/../../") << "scheme:b/c/d" << "../../d/../../" << "scheme:"; - QTest::newRow("relative+endslash+../../../..") << "scheme:b/c/d/" << "../../../.." << "scheme:"; - QTest::newRow("relative+endslash+../../../../") << "scheme:b/c/d/" << "../../../../" << "scheme:"; - QTest::newRow("relative+endslash+../../../..//") << "scheme:b/c/d/" << "../../../..//" << "scheme:"; - - // Resolve absolute without authority with relative + QTest::newRow("../a (5)") << QString::fromLatin1("/b") << QString::fromLatin1("../a") << QString::fromLatin1("/a"); QTest::newRow("../a (6)") << QString::fromLatin1("/b/a") << QString::fromLatin1("../a") << QString::fromLatin1("/a"); QTest::newRow("../a (7)") << QString::fromLatin1("/b/c/a") << QString::fromLatin1("../a") << QString::fromLatin1("/b/a"); QTest::newRow("../a (8)") << QString::fromLatin1("/b") << QString::fromLatin1("/a") << QString::fromLatin1("/a"); - QTest::newRow("noauthority+.") << "scheme:/a/b" << "." << "scheme:/a/"; - QTest::newRow("noauthority+./") << "scheme:/a/b" << "./" << "scheme:/a/"; - QTest::newRow("noauthority+.//") << "scheme:/a/b" << ".//" << "scheme:/a//"; - QTest::newRow("noauthority+./d") << "scheme:/a/b" << "./d" << "scheme:/a/d"; - QTest::newRow("noauthority+.//d") << "scheme:/a/b" << ".//d" << "scheme:/a//d"; - QTest::newRow("noauthority+..") << "scheme:/a/b" << ".." << "scheme:/"; - QTest::newRow("noauthority+../") << "scheme:/a/b" << "../" << "scheme:/"; - QTest::newRow("noauthority+..//") << "scheme:/a/b" << "..//" << "scheme:/"; - QTest::newRow("noauthority+../d") << "scheme:/a/b" << "../d" << "scheme:/d"; - QTest::newRow("noauthority+..//d") << "scheme:/a/b" << "..//d" << "scheme:/d"; // no double slash! - QTest::newRow("noauthority+../..") << "scheme:/a/b" << "../.." << "scheme:/"; - QTest::newRow("noauthority+../../") << "scheme:/a/b" << "../../" << "scheme:/"; - QTest::newRow("noauthority+../..//") << "scheme:/a/b" << "../..//" << "scheme:/"; - QTest::newRow("noauthority+../../d") << "scheme:/a/b" << "../../d" << "scheme:/d"; - QTest::newRow("noauthority+../..//d") << "scheme:/a/b" << "../..//d" << "scheme:/d"; // no double slash! // More tests from KDE QTest::newRow("brackets") << QString::fromLatin1("http://www.calorieking.com/personal/diary/") << QString::fromLatin1("/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458") << QString::fromLatin1("http://www.calorieking.com/personal/diary/rpc.php?C=jsrs1&F=getDiaryDay&P0=[2006-3-8]&U=1141858921458"); |