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). Change-Id: Iac1ff680887641888e00fffd17e14f3927e828ae Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
This commit is contained in:
parent
4b1547adc9
commit
09055d7211
@ -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