QUrl: set the host to empty but present for "file" URLs
We set it when manipulating full URLs. If you're creating them from parts, you may end up with one without a host. We will still fix that up in QUrl::toString() ("manipulates full URL"). This allows the path normalization code to avoid accidentally creating a URL with no host/authority and with a path that starts with double slash. [ChangeLog][QtCore][QUrl] Fixed a bug (regression from 6.7) where QUrl::resolved() could create invalid URLs when the relative URI being resolved contained a path with double slashes (e.g., combining "scheme:a" with "..//b.txt") Pick-to: 6.8 Fixes: QTBUG-133403 Change-Id: I3fe9d5fbd2efcaa66d66fffdc010e5a84066b641 Reviewed-by: David Faure <david.faure@kdab.com> (cherry picked from commit 7d05f5ed7d3472028e28a09eeda175bb1b1eeb00) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
d37960b35a
commit
86597d2891
@ -2717,8 +2717,12 @@ QUrl QUrl::resolved(const QUrl &relative) const
|
||||
qt_normalizePathSegments(
|
||||
&t.d->path,
|
||||
isLocalFile() ? QDirPrivate::DefaultNormalization : QDirPrivate::RemotePath);
|
||||
if (!t.d->hasAuthority())
|
||||
fixupNonAuthorityPath(&t.d->path);
|
||||
if (!t.d->hasAuthority()) {
|
||||
if (t.d->isLocalFile() && t.d->path.startsWith(u'/'))
|
||||
t.d->sectionIsPresent |= QUrlPrivate::Host;
|
||||
else
|
||||
fixupNonAuthorityPath(&t.d->path);
|
||||
}
|
||||
|
||||
#if defined(QURL_DEBUG)
|
||||
qDebug("QUrl(\"%ls\").resolved(\"%ls\") = \"%ls\"",
|
||||
@ -2893,6 +2897,11 @@ QUrl QUrl::adjusted(QUrl::FormattingOptions options) const
|
||||
d->appendPath(path, options | FullyEncoded, QUrlPrivate::Path);
|
||||
that.d->setPath(path, 0, path.size());
|
||||
}
|
||||
if (that.d->isLocalFile() && that.d->path.startsWith(u'/')) {
|
||||
// ensure absolute file URLs have an empty authority to comply with the
|
||||
// XDG file spec (note this may undo a RemoveAuthority)
|
||||
that.d->sectionIsPresent |= QUrlPrivate::Host;
|
||||
}
|
||||
return that;
|
||||
}
|
||||
|
||||
@ -3307,15 +3316,18 @@ static QString fromNativeSeparators(const QString &pathName)
|
||||
QUrl QUrl::fromLocalFile(const QString &localFile)
|
||||
{
|
||||
QUrl url;
|
||||
if (localFile.isEmpty())
|
||||
QString deslashified = fromNativeSeparators(localFile);
|
||||
if (deslashified.isEmpty())
|
||||
return url;
|
||||
QString scheme = fileScheme();
|
||||
QString deslashified = fromNativeSeparators(localFile);
|
||||
char16_t firstChar = deslashified.at(0).unicode();
|
||||
char16_t secondChar = deslashified.size() > 1 ? deslashified.at(1).unicode() : u'\0';
|
||||
|
||||
// magic for drives on windows
|
||||
if (deslashified.size() > 1 && deslashified.at(1) == u':' && deslashified.at(0) != u'/') {
|
||||
if (firstChar != u'/' && secondChar == u':') {
|
||||
deslashified.prepend(u'/');
|
||||
} else if (deslashified.startsWith("//"_L1)) {
|
||||
firstChar = u'/';
|
||||
} else if (firstChar == u'/' && secondChar == u'/') {
|
||||
// magic for shared drive on windows
|
||||
qsizetype indexOfPath = deslashified.indexOf(u'/', 2);
|
||||
QStringView hostSpec = QStringView{deslashified}.mid(2, indexOfPath - 2);
|
||||
@ -3339,9 +3351,15 @@ QUrl QUrl::fromLocalFile(const QString &localFile)
|
||||
deslashified.clear();
|
||||
}
|
||||
}
|
||||
if (firstChar == u'/') {
|
||||
// ensure absolute file URLs have an empty authority to comply with the XDG file spec
|
||||
url.detach();
|
||||
url.d->sectionIsPresent |= QUrlPrivate::Host;
|
||||
}
|
||||
|
||||
url.setScheme(scheme);
|
||||
url.setPath(deslashified, DecodedMode);
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
|
@ -1502,10 +1502,13 @@ void tst_QUrl::fromLocalFileNormalize_data()
|
||||
QTest::newRow("relative-dot") << QString::fromLatin1("./a.txt") << QString::fromLatin1("file:./a.txt") << QString::fromLatin1("file:a.txt");
|
||||
QTest::newRow("relative-dot-dot") << QString::fromLatin1("././a.txt") << QString::fromLatin1("file:././a.txt") << QString::fromLatin1("file:a.txt");
|
||||
QTest::newRow("relative-path-dotdot") << QString::fromLatin1("b/../a.txt") << QString::fromLatin1("file:b/../a.txt") << QString::fromLatin1("file:a.txt");
|
||||
QTest::newRow("relative-path-dotdot-dotdot") << QString::fromLatin1("b/../../a.txt") << QString::fromLatin1("file:b/../../a.txt") << QString::fromLatin1("file:../a.txt");
|
||||
QTest::newRow("absolute-path-dotdot") << QString::fromLatin1("/b/../a.txt") << QString::fromLatin1("file:///b/../a.txt") << QString::fromLatin1("file:///a.txt");
|
||||
QTest::newRow("absolute-path-dotdot-dotdot") << QString::fromLatin1("/b/../../a.txt") << QString::fromLatin1("file:///b/../../a.txt") << QString::fromLatin1("file:///../a.txt");
|
||||
QTest::newRow("absolute-path-slash") << QString::fromLatin1("/b/") << QString::fromLatin1("file:///b/") << QString::fromLatin1("file:///b/");
|
||||
QTest::newRow("absolute-path-slahs-dot") << QString::fromLatin1("/b/.") << QString::fromLatin1("file:///b/.") << QString::fromLatin1("file:///b/");
|
||||
QTest::newRow("absolute-path-slahs-dot-slash") << QString::fromLatin1("/b/./") << QString::fromLatin1("file:///b/./") << QString::fromLatin1("file:///b/");
|
||||
QTest::newRow("absolute-path-dotdot-slashslash") << QString::fromLatin1("/b/..//") << QString::fromLatin1("file:///b/..//") << QString::fromLatin1("file:////");
|
||||
}
|
||||
|
||||
void tst_QUrl::fromLocalFileNormalize()
|
||||
|
Loading…
x
Reference in New Issue
Block a user