summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-01-23 10:13:28 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-01-23 10:13:29 +0100
commite3da05f39a5b000bbb6194396d688bf26af771fd (patch)
tree6b1e0b84a2ef9b7abdd465c0aecb5688fcb40f1a /src/corelib
parent0c007a87be88f44151616b7251cfed5508913e0f (diff)
parent9822d57d858068cfe5a07281ef069ef8c4c7b7b3 (diff)
Merge remote-tracking branch 'origin/5.12.1' into 5.12
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/codecs/qwindowscodec.cpp6
-rw-r--r--src/corelib/doc/qtcore.qdocconf3
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp63
-rw-r--r--src/corelib/global/qglobal.cpp2
-rw-r--r--src/corelib/global/qnumeric_p.h2
-rw-r--r--src/corelib/io/qdir.cpp93
-rw-r--r--src/corelib/io/qdir_p.h12
-rw-r--r--src/corelib/io/qurl.cpp8
-rw-r--r--src/corelib/kernel/qtestsupport_core.cpp6
9 files changed, 102 insertions, 93 deletions
diff --git a/src/corelib/codecs/qwindowscodec.cpp b/src/corelib/codecs/qwindowscodec.cpp
index 6b703f7517..710935a65a 100644
--- a/src/corelib/codecs/qwindowscodec.cpp
+++ b/src/corelib/codecs/qwindowscodec.cpp
@@ -83,8 +83,12 @@ QString QWindowsLocalCodec::convertToUnicode(const char *chars, int length, Conv
len = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
prev, 2, wc.data(), wc.length());
if (len) {
- prepend = true;
sp.append(QChar(wc[0]));
+ if (mblen == 1) {
+ state->remainingChars = 0;
+ return sp;
+ }
+ prepend = true;
mb++;
mblen--;
wc[0] = 0;
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 5a42e21845..85dcde4607 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -45,6 +45,9 @@ excludedirs += snippets
excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \
../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc
+# Included in qttestlib.qdocconf instead
+excludefiles += ../kernel/qtestsupport_core.cpp
+
manifestmeta.highlighted.names = "QtCore/JSON Save Game Example" \
"QtCore/Local Fortune*"
diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp
deleted file mode 100644
index e793cb1f55..0000000000
--- a/src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the documentation of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** BSD License Usage
-** Alternatively, you may use this file under the terms of the BSD license
-** as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//! [0]
- MyObject obj;
- obj.startup();
- QTest::qWaitFor([&]() {
- return obj.isReady();
- }, 3000);
-//! [0]
-
-//! [1]
- int i = 0;
- while (myNetworkServerNotResponding() && i++ < 50)
- QTest::qWait(250);
-//! [1]
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index d15a8ba6ae..8d80a32ad5 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2025,6 +2025,8 @@ static const char *osVer_helper(QOperatingSystemVersion version = QOperatingSyst
return "Sierra";
case 13:
return "High Sierra";
+ case 14:
+ return "Mojave";
}
}
// unknown, future version
diff --git a/src/corelib/global/qnumeric_p.h b/src/corelib/global/qnumeric_p.h
index c762da80d3..4a225b2599 100644
--- a/src/corelib/global/qnumeric_p.h
+++ b/src/corelib/global/qnumeric_p.h
@@ -348,7 +348,7 @@ template <> inline bool mul_overflow(qint64 v1, qint64 v2, qint64 *r)
// as signed for the low bits and use a signed right shift to verify that
// 'high' is nothing but sign bits that match the sign of 'low'.
- qint64 high = __mulh(v1, v2);
+ qint64 high = Q_SMULH(v1, v2);
*r = qint64(quint64(v1) * quint64(v2));
return (*r >> 63) != high;
}
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 3007ffb958..f7778943c9 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -748,6 +748,21 @@ static int drivePrefixLength(const QString &path)
}
#endif // Q_OS_WIN
+static bool treatAsAbsolute(const QString &path)
+{
+ // ### Qt 6: be consistent about absolute paths
+
+ // QFileInfo will use the right FS-engine for virtual file-systems
+ // (e.g. resource paths). Unfortunately, for real file-systems, it relies
+ // on QFileSystemEntry's isRelative(), which is flawed on MS-Win, ignoring
+ // its (correct) isAbsolute(). So only use that isAbsolute() unless there's
+ // a colon in the path.
+ // FIXME: relies on virtual file-systems having colons in their prefixes.
+ // The case of an MS-absolute C:/... path happens to work either way.
+ return (path.contains(QLatin1Char(':')) && QFileInfo(path).isAbsolute())
+ || QFileSystemEntry(path).isAbsolute();
+}
+
/*!
Returns the path name of a file in the directory. Does \e not
check if the file actually exists in the directory; but see
@@ -759,13 +774,10 @@ static int drivePrefixLength(const QString &path)
*/
QString QDir::filePath(const QString &fileName) const
{
- const QDirPrivate* d = d_ptr.constData();
- // Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive.
- if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path
- ? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) {
+ if (treatAsAbsolute(fileName))
return fileName;
- }
+ const QDirPrivate* d = d_ptr.constData();
QString ret = d->dirEntry.filePath();
if (fileName.isEmpty())
return ret;
@@ -793,13 +805,10 @@ QString QDir::filePath(const QString &fileName) const
*/
QString QDir::absoluteFilePath(const QString &fileName) const
{
- const QDirPrivate* d = d_ptr.constData();
- // Mistrust our own isAbsolutePath() for real files; Q_OS_WIN needs a drive.
- if (fileName.startsWith(QLatin1Char(':')) // i.e. resource path
- ? isAbsolutePath(fileName) : QFileSystemEntry(fileName).isAbsolute()) {
+ if (treatAsAbsolute(fileName))
return fileName;
- }
+ const QDirPrivate* d = d_ptr.constData();
d->resolveAbsoluteEntry();
const QString absoluteDirPath = d->absoluteDirEntry.filePath();
if (fileName.isEmpty())
@@ -2160,9 +2169,10 @@ bool QDir::match(const QString &filter, const QString &fileName)
This method is shared with QUrl, so it doesn't deal with QDir::separator(),
nor does it remove the trailing slash, if any.
*/
-Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool allowUncPaths,
- bool *ok = nullptr)
+QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok)
{
+ const bool allowUncPaths = QDirPrivate::AllowUncPaths & flags;
+ const bool isRemote = QDirPrivate::RemotePath & flags;
const int len = name.length();
if (ok)
@@ -2184,14 +2194,30 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
i -= prefixLength;
// replicate trailing slash (i > 0 checks for emptiness of input string p)
- if (i > 0 && p[i] == '/') {
+ // except for remote paths because there can be /../ or /./ ending
+ if (i > 0 && p[i] == '/' && !isRemote) {
out[--used] = '/';
--i;
}
+ auto isDot = [](const ushort *p, int i) {
+ return i > 1 && p[i - 1] == '.' && p[i - 2] == '/';
+ };
+ auto isDotDot = [](const ushort *p, int i) {
+ return i > 2 && p[i - 1] == '.' && p[i - 2] == '.' && p[i - 3] == '/';
+ };
+
while (i >= 0) {
- // remove trailing slashes
+ // copy trailing slashes for remote urls
if (p[i] == '/') {
+ if (isRemote && !up) {
+ if (isDot(p, i)) {
+ i -= 2;
+ continue;
+ }
+ out[--used] = p[i];
+ }
+
--i;
continue;
}
@@ -2203,10 +2229,17 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
}
// detect up dir
- if (i >= 1 && p[i] == '.' && p[i-1] == '.'
- && (i == 1 || (i >= 2 && p[i-2] == '/'))) {
+ if (i >= 1 && p[i] == '.' && p[i-1] == '.' && (i < 2 || p[i - 2] == '/')) {
++up;
- i -= 2;
+ i -= i >= 2 ? 3 : 2;
+
+ if (isRemote) {
+ // moving up should consider empty path segments too (/path//../ -> /path/)
+ while (i > 0 && up && p[i] == '/') {
+ --up;
+ --i;
+ }
+ }
continue;
}
@@ -2216,7 +2249,27 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
// skip or copy
while (i >= 0) {
- if (p[i] == '/') { // do not copy slashes
+ if (p[i] == '/') {
+ // copy all slashes as is for remote urls if they are not part of /./ or /../
+ if (isRemote && !up) {
+ while (i > 0 && p[i] == '/' && !isDotDot(p, i)) {
+
+ if (isDot(p, i)) {
+ i -= 2;
+ continue;
+ }
+
+ out[--used] = p[i];
+ --i;
+ }
+
+ // in case of /./, jump over
+ if (isDot(p, i))
+ i -= 2;
+
+ break;
+ }
+
--i;
break;
}
@@ -2237,7 +2290,7 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all
*ok = prefixLength == 0 || up == 0;
// add remaining '..'
- while (up) {
+ while (up && !isRemote) {
if (used != len && out[used] != '/') // is not empty and there isn't already a '/'
out[--used] = '/';
out[--used] = '.';
@@ -2283,7 +2336,7 @@ static QString qt_cleanPath(const QString &path, bool *ok)
if (dir_separator != QLatin1Char('/'))
name.replace(dir_separator, QLatin1Char('/'));
- QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths, ok);
+ QString ret = qt_normalizePathSegments(name, OSSupportsUncPaths ? QDirPrivate::AllowUncPaths : QDirPrivate::DefaultNormalization, ok);
// Strip away last slash except for root directories
if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
diff --git a/src/corelib/io/qdir_p.h b/src/corelib/io/qdir_p.h
index 85d915223c..0f3ab7f899 100644
--- a/src/corelib/io/qdir_p.h
+++ b/src/corelib/io/qdir_p.h
@@ -59,6 +59,14 @@ QT_BEGIN_NAMESPACE
class QDirPrivate : public QSharedData
{
public:
+ enum PathNormalization {
+ DefaultNormalization = 0x00,
+ AllowUncPaths = 0x01,
+ RemotePath = 0x02
+ };
+ Q_DECLARE_FLAGS(PathNormalizations, PathNormalization)
+ Q_FLAGS(PathNormalizations)
+
explicit QDirPrivate(const QString &path, const QStringList &nameFilters_ = QStringList(),
QDir::SortFlags sort_ = QDir::SortFlags(QDir::Name | QDir::IgnoreCase),
QDir::Filters filters_ = QDir::AllEntries);
@@ -97,6 +105,10 @@ public:
mutable QFileSystemMetaData metaData;
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDirPrivate::PathNormalizations)
+
+Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, QDirPrivate::PathNormalizations flags, bool *ok = nullptr);
+
QT_END_NAMESPACE
#endif
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index b324df53b2..6d82981fd6 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -253,7 +253,8 @@
and contains no query or fragment, a local file path is returned.
\value StripTrailingSlash The trailing slash is removed from the path, if one is present.
\value NormalizePathSegments Modifies the path to remove redundant directory separators,
- and to resolve "."s and ".."s (as far as possible).
+ and to resolve "."s and ".."s (as far as possible). For non-local paths, adjacent
+ slashes are preserved.
Note that the case folding rules in \l{RFC 3491}{Nameprep}, which QUrl
conforms to, require host names to always be converted to lower case,
@@ -419,10 +420,9 @@
#endif
#include "private/qipaddress_p.h"
#include "qurlquery.h"
+#include "private/qdir_p.h"
QT_BEGIN_NAMESPACE
-extern QString qt_normalizePathSegments(const QString &name, bool allowUncPaths,
- bool *ok = nullptr); // qdir.cpp
inline static bool isHex(char c)
{
@@ -930,7 +930,7 @@ inline void QUrlPrivate::appendPath(QString &appendTo, QUrl::FormattingOptions o
{
QString thePath = path;
if (options & QUrl::NormalizePathSegments) {
- thePath = qt_normalizePathSegments(path, false);
+ thePath = qt_normalizePathSegments(path, isLocalFile() ? QDirPrivate::DefaultNormalization : QDirPrivate::RemotePath);
}
QStringRef thePathRef(&thePath);
diff --git a/src/corelib/kernel/qtestsupport_core.cpp b/src/corelib/kernel/qtestsupport_core.cpp
index e00ad75fef..c54b933f94 100644
--- a/src/corelib/kernel/qtestsupport_core.cpp
+++ b/src/corelib/kernel/qtestsupport_core.cpp
@@ -59,8 +59,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms)
#endif
}
-/*! \fn template <typename Functor> bool qWaitFor(Functor predicate, int timeout)
- \relates QTest
+/*! \fn template <typename Functor> bool QTest::qWaitFor(Functor predicate, int timeout)
Waits for \a timeout milliseconds or until the \a predicate returns true.
@@ -77,8 +76,7 @@ Q_CORE_EXPORT void QTestPrivate::qSleep(int ms)
*/
-/*! \fn void qWait(int ms)
- \relates QTest
+/*! \fn void QTest::qWait(int ms)
Waits for \a ms milliseconds. While waiting, events will be processed and
your test will stay responsive to user interface events or network communication.