summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorEdward Welbourne <edward.welbourne@qt.io>2018-07-31 11:34:23 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2018-07-31 11:34:23 +0000
commitcf2d59bfe8720627e016195903e16cd0c97fa612 (patch)
tree5cc0755d649d606867bf6168a091a91c9d3e6f3d /src/corelib
parent7621bb0f3bba69e0b2849974a335dff4742c8e95 (diff)
parent23c9d4c98f3c6729b56700edc1d7144b444b16db (diff)
Merge "Merge branch '5.11' into dev" into refs/staging/dev
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp2
-rw-r--r--src/corelib/io/qdir.cpp96
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp7
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp17
-rw-r--r--src/corelib/io/qurl.cpp2
-rw-r--r--src/corelib/kernel/qcore_unix.cpp20
-rw-r--r--src/corelib/kernel/qcore_unix_p.h8
-rw-r--r--src/corelib/kernel/qcoreevent.cpp6
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp24
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h9
-rw-r--r--src/corelib/plugin/qlibrary.cpp5
-rw-r--r--src/corelib/plugin/qpluginloader.cpp6
-rw-r--r--src/corelib/serialization/qdatastream.cpp2
-rw-r--r--src/corelib/serialization/qjsondocument.cpp2
-rw-r--r--src/corelib/serialization/qjsonvalue.cpp1
-rw-r--r--src/corelib/tools/qchar.h2
-rw-r--r--src/corelib/tools/qcollator.cpp14
17 files changed, 156 insertions, 67 deletions
diff --git a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
index 27565a7878..cc3f689710 100644
--- a/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
+++ b/src/corelib/doc/snippets/code/src_corelib_tools_qlistdata.cpp
@@ -131,7 +131,7 @@ list.removeAll("sun");
QList<QString> list;
list << "sun" << "cloud" << "sun" << "rain";
list.removeOne("sun");
-// list: ["cloud", ,"sun", "rain"]
+// list: ["cloud", "sun", "rain"]
//! [10]
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index 06eacf5455..7c0a48f8f2 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -715,6 +715,37 @@ QString QDir::dirName() const
return d->dirEntry.fileName();
}
+
+#ifdef Q_OS_WIN
+static int drivePrefixLength(const QString &path)
+{
+ // Used to extract path's drive for use as prefix for an "absolute except for drive" path
+ const int size = path.length();
+ int drive = 2; // length of drive prefix
+ if (size > 1 && path.at(1).unicode() == ':') {
+ if (Q_UNLIKELY(!path.at(0).isLetter()))
+ return 0;
+ } else if (path.startsWith(QLatin1String("//"))) {
+ // UNC path; use its //server/share part as "drive" - it's as sane a
+ // thing as we can do.
+ for (int i = 2; i-- > 0; ) { // Scan two "path fragments":
+ while (drive < size && path.at(drive).unicode() == '/')
+ drive++;
+ if (drive >= size) {
+ qWarning("Base directory starts with neither a drive nor a UNC share: %s",
+ qUtf8Printable(QDir::toNativeSeparators(path)));
+ return 0;
+ }
+ while (drive < size && path.at(drive).unicode() != '/')
+ drive++;
+ }
+ } else {
+ return 0;
+ }
+ return drive;
+}
+#endif // Q_OS_WIN
+
/*!
Returns the path name of a file in the directory. Does \e not
check if the file actually exists in the directory; but see
@@ -727,16 +758,27 @@ QString QDir::dirName() const
QString QDir::filePath(const QString &fileName) const
{
const QDirPrivate* d = d_ptr.constData();
- if (isAbsolutePath(fileName))
+ // 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()) {
return fileName;
+ }
QString ret = d->dirEntry.filePath();
- if (!fileName.isEmpty()) {
- if (!ret.isEmpty() && ret[(int)ret.length()-1] != QLatin1Char('/') && fileName[0] != QLatin1Char('/'))
- ret += QLatin1Char('/');
- ret += fileName;
+ if (fileName.isEmpty())
+ return ret;
+
+#ifdef Q_OS_WIN
+ if (fileName.startsWith(QLatin1Char('/')) || fileName.startsWith(QLatin1Char('\\'))) {
+ // Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
+ const int drive = drivePrefixLength(ret);
+ return drive > 0 ? ret.leftRef(drive) % fileName : fileName;
}
- return ret;
+#endif // Q_OS_WIN
+
+ if (ret.isEmpty() || ret.endsWith(QLatin1Char('/')))
+ return ret % fileName;
+ return ret % QLatin1Char('/') % fileName;
}
/*!
@@ -750,9 +792,11 @@ QString QDir::filePath(const QString &fileName) const
QString QDir::absoluteFilePath(const QString &fileName) const
{
const QDirPrivate* d = d_ptr.constData();
- // Don't trust our own isAbsolutePath(); Q_OS_WIN needs a drive.
- if (QFileSystemEntry(fileName).isAbsolute())
+ // 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()) {
return fileName;
+ }
d->resolveAbsoluteEntry();
const QString absoluteDirPath = d->absoluteDirEntry.filePath();
@@ -760,35 +804,15 @@ QString QDir::absoluteFilePath(const QString &fileName) const
return absoluteDirPath;
#ifdef Q_OS_WIN
// Handle the "absolute except for drive" case (i.e. \blah not c:\blah):
- int size = absoluteDirPath.length();
- if ((fileName.startsWith(QLatin1Char('/'))
- || fileName.startsWith(QLatin1Char('\\')))
- && size > 1) {
+ if (fileName.startsWith(QLatin1Char('/')) || fileName.startsWith(QLatin1Char('\\'))) {
// Combine absoluteDirPath's drive with fileName
- int drive = 2; // length of drive prefix
- if (Q_UNLIKELY(absoluteDirPath.at(1).unicode() != ':')) {
- // Presumably, absoluteDirPath is an UNC path; use its //server/share
- // part as "drive" - it's as sane a thing as we can do.
- for (int i = 2; i-- > 0; ) { // Scan two "path fragments":
- while (drive < size && absoluteDirPath.at(drive).unicode() == '/')
- drive++;
- if (drive >= size) {
- qWarning("Base directory starts with neither a drive nor a UNC share: %s",
- qPrintable(QDir::toNativeSeparators(absoluteDirPath)));
- return QString();
- }
- while (drive < size && absoluteDirPath.at(drive).unicode() != '/')
- drive++;
- }
- // We'll append fileName, which starts with a slash; so omit trailing slash:
- if (absoluteDirPath.at(drive).unicode() == '/')
- drive--;
- } else if (!absoluteDirPath.at(0).isLetter()) {
- qWarning("Base directory's drive is not a letter: %s",
- qPrintable(QDir::toNativeSeparators(absoluteDirPath)));
- return QString();
- }
- return absoluteDirPath.leftRef(drive) % fileName;
+ const int drive = drivePrefixLength(absoluteDirPath);
+ if (Q_LIKELY(drive))
+ return absoluteDirPath.leftRef(drive) % fileName;
+
+ qWarning("Base directory's drive is not a letter: %s",
+ qUtf8Printable(QDir::toNativeSeparators(absoluteDirPath)));
+ return QString();
}
#endif // Q_OS_WIN
if (!absoluteDirPath.endsWith(QLatin1Char('/')))
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index bf648cdfe0..90ad0126d6 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -636,6 +636,7 @@ bool QFSFileEngine::setFileTime(const QDateTime &newDate, FileTime time)
uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags)
{
+ qint64 maxFileOffset = std::numeric_limits<QT_OFF_T>::max();
#if (defined(Q_OS_LINUX) || defined(Q_OS_ANDROID)) && Q_PROCESSOR_WORDSIZE == 4
// The Linux mmap2 system call on 32-bit takes a page-shifted 32-bit
// integer so the maximum offset is 1 << (32+12) (the shift is always 12,
@@ -644,9 +645,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
// and Bionic): all of them do the right shift, but don't confirm that the
// result fits into the 32-bit parameter to the kernel.
- static qint64 MaxFileOffset = (Q_INT64_C(1) << (32+12)) - 1;
-#else
- static qint64 MaxFileOffset = std::numeric_limits<QT_OFF_T>::max();
+ maxFileOffset = qMin((Q_INT64_C(1) << (32+12)) - 1, maxFileOffset);
#endif
Q_Q(QFSFileEngine);
@@ -655,7 +654,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
return 0;
}
- if (offset < 0 || offset > MaxFileOffset
+ if (offset < 0 || offset > maxFileOffset
|| size < 0 || quint64(size) > quint64(size_t(-1))) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
return 0;
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index eeb02419c3..1809861fc6 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -129,7 +129,7 @@ static GUID writableSpecialFolderId(QStandardPaths::StandardLocation type)
}
// Convenience for SHGetKnownFolderPath().
-static QString sHGetKnownFolderPath(const GUID &clsid, QStandardPaths::StandardLocation type, bool warn = false)
+static QString sHGetKnownFolderPath(const GUID &clsid)
{
QString result;
typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*);
@@ -141,11 +141,6 @@ static QString sHGetKnownFolderPath(const GUID &clsid, QStandardPaths::StandardL
if (Q_LIKELY(sHGetKnownFolderPath && SUCCEEDED(sHGetKnownFolderPath(clsid, KF_FLAG_DONT_VERIFY, 0, &path)))) {
result = convertCharArray(path);
CoTaskMemFree(path);
- } else {
- if (warn) {
- qErrnoWarning("SHGetKnownFolderPath() failed for standard location \"%s\".",
- qPrintable(displayName(type)));
- }
}
return result;
}
@@ -155,7 +150,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QString result;
switch (type) {
case DownloadLocation:
- result = sHGetKnownFolderPath(FOLDERID_Downloads, type);
+ result = sHGetKnownFolderPath(FOLDERID_Downloads);
if (result.isEmpty())
result = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
break;
@@ -164,7 +159,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
// Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
// location for everyone. Most applications seem to be using a
// cache directory located in their AppData directory
- result = sHGetKnownFolderPath(writableSpecialFolderId(AppLocalDataLocation), type, /* warn */ true);
+ result = sHGetKnownFolderPath(writableSpecialFolderId(AppLocalDataLocation));
if (!result.isEmpty()) {
appendTestMode(result);
appendOrganizationAndApp(result);
@@ -173,7 +168,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
break;
case GenericCacheLocation:
- result = sHGetKnownFolderPath(writableSpecialFolderId(GenericDataLocation), type, /* warn */ true);
+ result = sHGetKnownFolderPath(writableSpecialFolderId(GenericDataLocation));
if (!result.isEmpty()) {
appendTestMode(result);
result += QLatin1String("/cache");
@@ -190,7 +185,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
break;
default:
- result = sHGetKnownFolderPath(writableSpecialFolderId(type), type, /* warn */ isConfigLocation(type));
+ result = sHGetKnownFolderPath(writableSpecialFolderId(type));
if (!result.isEmpty() && isConfigLocation(type)) {
appendTestMode(result);
if (!isGenericConfigLocation(type))
@@ -214,7 +209,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
// type-specific handling goes here
if (isConfigLocation(type)) {
- QString programData = sHGetKnownFolderPath(FOLDERID_ProgramData, type);
+ QString programData = sHGetKnownFolderPath(FOLDERID_ProgramData);
if (!programData.isEmpty()) {
if (!isGenericConfigLocation(type))
appendOrganizationAndApp(programData);
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 25881b9c62..399c3b8861 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -2545,7 +2545,7 @@ int QUrl::port(int defaultPort) const
The \a path data is interpreted according to \a mode: in StrictMode,
any '%' characters must be followed by exactly two hexadecimal characters
and some characters (including space) are not allowed in undecoded form. In
- TolerantMode (the default), all characters are accepted in undecoded form and the
+ TolerantMode, all characters are accepted in undecoded form and the
tolerant parser will correct stray '%' not followed by two hex characters.
In DecodedMode, '%' stand for themselves and encoded characters are not
possible.
diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp
index eb98cbef8f..18c031f137 100644
--- a/src/corelib/kernel/qcore_unix.cpp
+++ b/src/corelib/kernel/qcore_unix.cpp
@@ -44,6 +44,12 @@
#include <stdlib.h>
+#ifdef __GLIBC__
+# include <sys/syscall.h>
+# include <pthread.h>
+# include <unistd.h>
+#endif
+
#ifdef Q_OS_MAC
#include <mach/mach_time.h>
#endif
@@ -79,6 +85,20 @@ QByteArray qt_readlink(const char *path)
return buf;
}
+#if defined(Q_PROCESSOR_X86_32) && defined(__GLIBC__)
+# if !__GLIBC_PREREQ(2, 22)
+// glibc prior to release 2.22 had a bug that suppresses the third argument to
+// open() / open64() / openat(), causing file creation with O_TMPFILE to have
+// the wrong permissions. So we bypass the glibc implementation and go straight
+// for the syscall. See
+// https://sourceware.org/git/?p=glibc.git;a=commit;h=65f6f938cd562a614a68e15d0581a34b177ec29d
+int qt_open64(const char *pathname, int flags, mode_t mode)
+{
+ return syscall(SYS_open, pathname, flags | O_LARGEFILE, mode);
+}
+# endif
+#endif
+
#ifndef QT_BOOTSTRAPPED
#if QT_CONFIG(poll_pollts)
diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h
index e538a7e22b..cb98bef347 100644
--- a/src/corelib/kernel/qcore_unix_p.h
+++ b/src/corelib/kernel/qcore_unix_p.h
@@ -176,6 +176,14 @@ inline void qt_ignore_sigpipe()
}
}
+#if defined(Q_PROCESSOR_X86_32) && defined(__GLIBC__)
+# if !__GLIBC_PREREQ(2, 22)
+int qt_open64(const char *pathname, int flags, mode_t);
+# undef QT_OPEN
+# define QT_OPEN qt_open64
+# endif
+#endif
+
// don't call QT_OPEN or ::open
// call qt_safe_open
static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 0777)
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index e34fe3f955..cacbb1e495 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -204,6 +204,12 @@ QT_BEGIN_NAMESPACE
\value Scroll The object needs to scroll to the supplied position (QScrollEvent).
\value Shortcut Key press in child for shortcut key handling (QShortcutEvent).
\value ShortcutOverride Key press in child, for overriding shortcut key handling (QKeyEvent).
+ When a shortcut is about to trigger, \c ShortcutOverride
+ is sent to the active window. This allows clients (e.g. widgets)
+ to signal that they will handle the shortcut themselves, by
+ accepting the event. If the shortcut override is accepted, the
+ event is delivered as a normal key press to the focus widget.
+ Otherwise, it triggers the shortcut action, if one exists.
\value Show Widget was shown on screen (QShowEvent).
\value ShowToParent A child widget has been shown.
\value SockAct Socket activated, used to implement QSocketNotifier.
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index ec6d98cc3c..0b35f41ca3 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -58,6 +59,29 @@
QT_BEGIN_NAMESPACE
+static inline int metaDataSignatureLength()
+{
+ return sizeof("QTMETADATA ") - 1;
+}
+
+QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype sectionSize)
+{
+ raw += metaDataSignatureLength();
+ sectionSize -= metaDataSignatureLength();
+
+ // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h)
+ uint size = qFromLittleEndian<uint>(raw + 8);
+ // but the maximum size of binary JSON is 128 MB
+ size = qMin(size, 128U * 1024 * 1024);
+ // and it doesn't include the size of the header (8 bytes)
+ size += 8;
+ // finally, it can't be bigger than the file or section size
+ size = qMin(sectionSize, qsizetype(size));
+
+ QByteArray json(raw, size);
+ return QJsonDocument::fromBinaryData(json);
+}
+
class QFactoryLoaderPrivate : public QObjectPrivate
{
Q_DECLARE_PUBLIC(QFactoryLoader)
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index 7be18942ae..fe722999ae 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -66,14 +66,7 @@
QT_BEGIN_NAMESPACE
-inline QJsonDocument qJsonFromRawLibraryMetaData(const char *raw)
-{
- raw += strlen("QTMETADATA ");
- // the size of the embedded JSON object can be found 8 bytes into the data (see qjson_p.h),
- // but doesn't include the size of the header (8 bytes)
- QByteArray json(raw, qFromLittleEndian<uint>(*(const uint *)(raw + 8)) + 8);
- return QJsonDocument::fromBinaryData(json);
-}
+QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype size);
class QFactoryLoaderPrivate;
class Q_CORE_EXPORT QFactoryLoader : public QObject
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 4b55ead668..869ef6181f 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -317,7 +317,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
if (pos >= 0) {
if (hasMetaData) {
const char *data = filedata + pos;
- QJsonDocument doc = qJsonFromRawLibraryMetaData(data);
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(data, qsizetype(fdlen));
lib->metaData = doc.object();
if (qt_debug_component())
qWarning("Found metadata in lib %s, metadata=\n%s\n",
@@ -691,7 +691,8 @@ static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryP
if (!szData)
return false;
- QJsonDocument doc = qJsonFromRawLibraryMetaData(szData);
+ // the data is already loaded, so the size doesn't matter
+ QJsonDocument doc = qJsonFromRawLibraryMetaData(szData, INT_MAX);
if (doc.isNull())
return false;
priv->metaData = doc.object();
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index aab00cc7eb..83cbcd2b44 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2018 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -474,7 +475,10 @@ QVector<QStaticPlugin> QPluginLoader::staticPlugins()
*/
QJsonObject QStaticPlugin::metaData() const
{
- return qJsonFromRawLibraryMetaData(rawMetaData()).object();
+ // the data is already loaded, so this doesn't matter
+ qsizetype rawMetaDataSize = INT_MAX;
+
+ return qJsonFromRawLibraryMetaData(rawMetaData(), rawMetaDataSize).object();
}
QT_END_NAMESPACE
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index 54d1ae816b..60467b4824 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -1082,7 +1082,7 @@ QDataStream &QDataStream::readBytes(char *&s, uint &l)
Reads at most \a len bytes from the stream into \a s and returns the number of
bytes read. If an error occurs, this function returns -1.
- The buffer \a s must be preallocated. The data is \e not encoded.
+ The buffer \a s must be preallocated. The data is \e not decoded.
\sa readBytes(), QIODevice::read(), writeRawData()
*/
diff --git a/src/corelib/serialization/qjsondocument.cpp b/src/corelib/serialization/qjsondocument.cpp
index ab27b45fda..5018f7c267 100644
--- a/src/corelib/serialization/qjsondocument.cpp
+++ b/src/corelib/serialization/qjsondocument.cpp
@@ -344,6 +344,7 @@ QByteArray QJsonDocument::toJson() const
/*!
\enum QJsonDocument::JsonFormat
+ \since 5.1
This value defines the format of the JSON byte array produced
when converting to a QJsonDocument using toJson().
@@ -368,6 +369,7 @@ QByteArray QJsonDocument::toJson() const
*/
/*!
+ \since 5.1
Converts the QJsonDocument to a UTF-8 encoded JSON document in the provided \a format.
\sa fromJson(), JsonFormat
diff --git a/src/corelib/serialization/qjsonvalue.cpp b/src/corelib/serialization/qjsonvalue.cpp
index 3c5b0a0e02..4469302e31 100644
--- a/src/corelib/serialization/qjsonvalue.cpp
+++ b/src/corelib/serialization/qjsonvalue.cpp
@@ -588,6 +588,7 @@ bool QJsonValue::toBool(bool defaultValue) const
}
/*!
+ \since 5.2
Converts the value to an int and returns it.
If type() is not Double or the value is not a whole number,
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index 84df8accc5..8590b91ba3 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -93,7 +93,9 @@ public:
Q_STATIC_ASSERT(sizeof(wchar_t) == sizeof(ushort));
#endif
#if defined(Q_OS_WIN) || defined(Q_CLANG_QDOC)
+# if !defined(_WCHAR_T_DEFINED) || defined(_NATIVE_WCHAR_T_DEFINED)
Q_DECL_CONSTEXPR QChar(wchar_t ch) Q_DECL_NOTHROW : ucs(ushort(ch)) {} // implicit
+# endif
#endif
#ifndef QT_NO_CAST_FROM_ASCII
diff --git a/src/corelib/tools/qcollator.cpp b/src/corelib/tools/qcollator.cpp
index f1e3d6652d..5155badcf8 100644
--- a/src/corelib/tools/qcollator.cpp
+++ b/src/corelib/tools/qcollator.cpp
@@ -89,7 +89,12 @@ QCollator::QCollator(const QLocale &locale)
QCollator::QCollator(const QCollator &other)
: d(other.d)
{
- d->ref.ref();
+ if (d) {
+ // Ensure clean, lest both copies try to init() at the same time:
+ if (d->dirty)
+ d->init();
+ d->ref.ref();
+ }
}
/*!
@@ -110,7 +115,12 @@ QCollator &QCollator::operator=(const QCollator &other)
if (d && !d->ref.deref())
delete d;
d = other.d;
- if (d) d->ref.ref();
+ if (d) {
+ // Ensure clean, lest both copies try to init() at the same time:
+ if (d->dirty)
+ d->init();
+ d->ref.ref();
+ }
}
return *this;
}