QUrl::resolved: avoid detaching from paths that don't have dot segments
This can happen in any number of cases where neither the base URI nor the relative one had a "." or ".." segment. In particular, we want to avoid detaching in the case where the new path is the same as either of the base or relative URI's, which can happen when the other was empty (and mergePaths() didn't have to prepend a slash). Pick-to: 6.8.0 6.7 6.5 Change-Id: Iac1ff680887641888e00fffd17e14f3927e828ae Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 09055d7211b1f8ba9fdec141a1e919faee1c1676) Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
This commit is contained in:
parent
21eff6644d
commit
7b45dc49bb
@ -1541,12 +1541,33 @@ static void removeDotsFromPath(QString *path)
|
||||
// The input buffer is initialized with the now-appended path
|
||||
// components and the output buffer is initialized to the empty
|
||||
// string.
|
||||
const QChar *in = path->constBegin();
|
||||
|
||||
// Scan the input for a "." or ".." segment. If there isn't any, then we
|
||||
// don't need to modify this path at all.
|
||||
qsizetype modidx = [&] {
|
||||
bool lastWasSlash = true;
|
||||
for (qsizetype i = 0, n = path->size(); i < n; ++i) {
|
||||
if (lastWasSlash && in[i] == u'.') {
|
||||
if (i + 1 == n || in[i + 1] == u'/')
|
||||
return i;
|
||||
if (in[i + 1] == u'.' && (i + 2 == n || in[i + 2] == u'/'))
|
||||
return i;
|
||||
}
|
||||
lastWasSlash = in[i] == u'/';
|
||||
}
|
||||
return qsizetype(-1);
|
||||
}();
|
||||
if (modidx < 0)
|
||||
return;
|
||||
|
||||
QChar *out = path->data();
|
||||
const QChar *in = out;
|
||||
const QChar *end = out + path->size();
|
||||
out += modidx;
|
||||
in = out;
|
||||
|
||||
// We implement a modified algorithm compared to RFC 3986, for efficiency.
|
||||
while (in < end) {
|
||||
do {
|
||||
#if 0 // to see in the debugger
|
||||
QStringView output(path->constBegin(), out);
|
||||
QStringView input(in, end);
|
||||
@ -1607,7 +1628,7 @@ static void removeDotsFromPath(QString *path)
|
||||
// If it is neither, then we copy this segment.
|
||||
while (in < end && in->unicode() != '/')
|
||||
*out++ = *in++;
|
||||
}
|
||||
} while (in < end);
|
||||
path->truncate(out - path->constBegin());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user