diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-01-23 10:13:28 +0100 |
---|---|---|
committer | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2019-01-23 10:13:29 +0100 |
commit | e3da05f39a5b000bbb6194396d688bf26af771fd (patch) | |
tree | 6b1e0b84a2ef9b7abdd465c0aecb5688fcb40f1a /src/corelib | |
parent | 0c007a87be88f44151616b7251cfed5508913e0f (diff) | |
parent | 9822d57d858068cfe5a07281ef069ef8c4c7b7b3 (diff) |
Merge remote-tracking branch 'origin/5.12.1' into 5.12
Change-Id: Icebd151eae0cf9d400319a42573290d1a911ce26
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/codecs/qwindowscodec.cpp | 6 | ||||
-rw-r--r-- | src/corelib/doc/qtcore.qdocconf | 3 | ||||
-rw-r--r-- | src/corelib/doc/snippets/code/src_corelib_kernel_qtestsupport_core.cpp | 63 | ||||
-rw-r--r-- | src/corelib/global/qglobal.cpp | 2 | ||||
-rw-r--r-- | src/corelib/global/qnumeric_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qdir.cpp | 93 | ||||
-rw-r--r-- | src/corelib/io/qdir_p.h | 12 | ||||
-rw-r--r-- | src/corelib/io/qurl.cpp | 8 | ||||
-rw-r--r-- | src/corelib/kernel/qtestsupport_core.cpp | 6 |
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. |