summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2016-01-21 08:17:21 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2016-01-21 08:17:21 +0100
commit158a3a4159bdc5a49caecd63e021dacbc06cf23c (patch)
treec3ed9aee6cabd46e5e8615b3815b92d32857c4da /src/corelib
parent26ece94a68fb5ae680c5639716b06c4e1ae979a8 (diff)
parent7b2fb038ae4b8b9231ae989ad309b6eca107a858 (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/corelib/io/qiodevice_p.h src/corelib/kernel/qvariant_p.h src/corelib/tools/qsimd.cpp src/gui/kernel/qguiapplication.cpp tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp Change-Id: I742a093cbb231b282b43e463ec67173e0d29f57a
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/codecs/qutfcodec.cpp9
-rw-r--r--src/corelib/io/qfiledevice.cpp2
-rw-r--r--src/corelib/io/qfileselector.cpp15
-rw-r--r--src/corelib/io/qfsfileengine.cpp46
-rw-r--r--src/corelib/io/qlockfile_p.h2
-rw-r--r--src/corelib/io/qlockfile_unix.cpp42
-rw-r--r--src/corelib/io/qsettings.cpp8
-rw-r--r--src/corelib/io/qurl.cpp53
-rw-r--r--src/corelib/io/qwinoverlappedionotifier.cpp2
-rw-r--r--src/corelib/json/qjson_p.h2
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp44
-rw-r--r--src/corelib/kernel/qeventdispatcher_win_p.h2
-rw-r--r--src/corelib/kernel/qsignalmapper.cpp3
-rw-r--r--src/corelib/kernel/qvariant.cpp9
-rw-r--r--src/corelib/kernel/qvariant_p.h86
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp10
-rw-r--r--src/corelib/thread/qexception.cpp4
-rw-r--r--src/corelib/thread/qexception.h2
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h6
-rw-r--r--src/corelib/tools/qdatetime.cpp83
-rw-r--r--src/corelib/tools/qdatetimeparser.cpp32
-rw-r--r--src/corelib/tools/qlocale.cpp7
-rw-r--r--src/corelib/tools/qsharedpointer.h6
-rw-r--r--src/corelib/tools/qstring.h18
24 files changed, 292 insertions, 201 deletions
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index 25c240d17a..230ec1ccb3 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -392,6 +392,7 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte
// main body, stateless decoding
res = 0;
const uchar *nextAscii = src;
+ const uchar *start = src;
while (res >= 0 && src < end) {
if (src >= nextAscii && simdDecodeAscii(dst, nextAscii, src, end))
break;
@@ -400,9 +401,11 @@ QString QUtf8::convertToUnicode(const char *chars, int len, QTextCodec::Converte
res = QUtf8Functions::fromUtf8<QUtf8BaseTraits>(ch, dst, src, end);
if (!headerdone && res >= 0) {
headerdone = true;
- // eat the UTF-8 BOM
- if (dst[-1] == 0xfeff)
- --dst;
+ if (src == start + 3) { // 3 == sizeof(utf8-bom)
+ // eat the UTF-8 BOM (it can only appear at the beginning of the string).
+ if (dst[-1] == 0xfeff)
+ --dst;
+ }
}
if (res == QUtf8BaseTraits::Error) {
res = 0;
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index 0817dbec41..8ea2206e6b 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -566,7 +566,7 @@ qint64 QFileDevice::writeData(const char *data, qint64 len)
char *writePointer = d->writeBuffer.reserve(len);
if (len == 1)
*writePointer = *data;
- else
+ else if (len)
::memcpy(writePointer, data, len);
return len;
}
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index 9cca3793a2..a84a03837d 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -229,9 +229,9 @@ QString QFileSelector::select(const QString &filePath) const
static bool isLocalScheme(const QString &file)
{
- bool local = file == QStringLiteral("qrc");
+ bool local = file == QLatin1String("qrc");
#ifdef Q_OS_ANDROID
- local |= file == QStringLiteral("assets");
+ local |= file == QLatin1String("assets");
#endif
return local;
}
@@ -250,9 +250,16 @@ QUrl QFileSelector::select(const QUrl &filePath) const
return filePath;
QUrl ret(filePath);
if (isLocalScheme(filePath.scheme())) {
- QString equivalentPath = QLatin1Char(':') + filePath.path();
+ QLatin1String scheme(":");
+#ifdef Q_OS_ANDROID
+ // use other scheme because ":" means "qrc" here
+ if (filePath.scheme() == QLatin1String("assets"))
+ scheme = QLatin1String("assets:");
+#endif
+
+ QString equivalentPath = scheme + filePath.path();
QString selectedPath = d->select(equivalentPath);
- ret.setPath(selectedPath.remove(0, 1));
+ ret.setPath(selectedPath.remove(0, scheme.size()));
} else {
ret = QUrl::fromLocalFile(d->select(ret.toLocalFile()));
}
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index 41feca8a77..7509307839 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -730,29 +730,33 @@ qint64 QFSFileEnginePrivate::writeFdFh(const char *data, qint64 len)
qint64 writtenBytes = 0;
- if (fh) {
- // Buffered stdlib mode.
-
- size_t result;
- do {
- result = fwrite(data + writtenBytes, 1, size_t(len - writtenBytes), fh);
- writtenBytes += result;
- } while (result == 0 ? errno == EINTR : writtenBytes < len);
+ if (len) { // avoid passing nullptr to fwrite() or QT_WRITE() (UB)
- } else if (fd != -1) {
- // Unbuffered stdio mode.
+ if (fh) {
+ // Buffered stdlib mode.
+
+ size_t result;
+ do {
+ result = fwrite(data + writtenBytes, 1, size_t(len - writtenBytes), fh);
+ writtenBytes += result;
+ } while (result == 0 ? errno == EINTR : writtenBytes < len);
+
+ } else if (fd != -1) {
+ // Unbuffered stdio mode.
+
+ SignedIOType result;
+ do {
+ // calculate the chunk size
+ // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks
+ // we limit to the size of the signed type, otherwise we could get a negative number as a result
+ quint64 wantedBytes = quint64(len) - quint64(writtenBytes);
+ UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max();
+ if (chunkSize > wantedBytes)
+ chunkSize = wantedBytes;
+ result = QT_WRITE(fd, data + writtenBytes, chunkSize);
+ } while (result > 0 && (writtenBytes += result) < len);
+ }
- SignedIOType result;
- do {
- // calculate the chunk size
- // on Windows or 32-bit no-largefile Unix, we'll need to read in chunks
- // we limit to the size of the signed type, otherwise we could get a negative number as a result
- quint64 wantedBytes = quint64(len) - quint64(writtenBytes);
- UnsignedIOType chunkSize = std::numeric_limits<SignedIOType>::max();
- if (chunkSize > wantedBytes)
- chunkSize = wantedBytes;
- result = QT_WRITE(fd, data + writtenBytes, chunkSize);
- } while (result > 0 && (writtenBytes += result) < len);
}
if (len && writtenBytes == 0) {
diff --git a/src/corelib/io/qlockfile_p.h b/src/corelib/io/qlockfile_p.h
index 7ea79553e4..b41b9b4604 100644
--- a/src/corelib/io/qlockfile_p.h
+++ b/src/corelib/io/qlockfile_p.h
@@ -84,7 +84,7 @@ public:
static QString processNameByPid(qint64 pid);
#ifdef Q_OS_UNIX
- static int checkFcntlWorksAfterFlock();
+ static int checkFcntlWorksAfterFlock(const QString &fn);
#endif
QString fileName;
diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp
index 8bb94ee6c1..14ad103c4e 100644
--- a/src/corelib/io/qlockfile_unix.cpp
+++ b/src/corelib/io/qlockfile_unix.cpp
@@ -45,6 +45,10 @@
#include "QtCore/qfileinfo.h"
#include "QtCore/qdebug.h"
#include "QtCore/qdatetime.h"
+#include "QtCore/qfileinfo.h"
+#include "QtCore/qcache.h"
+#include "QtCore/qglobalstatic.h"
+#include "QtCore/qmutex.h"
#include "private/qcore_unix_p.h" // qt_safe_open
#include "private/qabstractfileengine_p.h"
@@ -100,10 +104,10 @@ static qint64 qt_write_loop(int fd, const char *data, qint64 len)
return pos;
}
-int QLockFilePrivate::checkFcntlWorksAfterFlock()
+int QLockFilePrivate::checkFcntlWorksAfterFlock(const QString &fn)
{
#ifndef QT_NO_TEMPORARYFILE
- QTemporaryFile file;
+ QTemporaryFile file(fn);
if (!file.open())
return 0;
const int fd = file.d_func()->engine()->handle();
@@ -125,24 +129,34 @@ int QLockFilePrivate::checkFcntlWorksAfterFlock()
#endif
}
-static QBasicAtomicInt fcntlOK = Q_BASIC_ATOMIC_INITIALIZER(-1);
+// Cache the result of checkFcntlWorksAfterFlock for each directory a lock
+// file is created in because in some filesystems, like NFS, both locks
+// are the same. This does not take into account a filesystem changing.
+// QCache is set to hold a maximum of 10 entries, this is to avoid unbounded
+// growth, this is caching directories of files and it is assumed a low number
+// will be sufficient.
+typedef QCache<QString, bool> CacheType;
+Q_GLOBAL_STATIC_WITH_ARGS(CacheType, fcntlOK, (10));
+static QBasicMutex fcntlLock;
/*!
\internal
Checks that the OS isn't using POSIX locks to emulate flock().
OS X is one of those.
*/
-static bool fcntlWorksAfterFlock()
+static bool fcntlWorksAfterFlock(const QString &fn)
{
- int value = fcntlOK.load();
- if (Q_UNLIKELY(value == -1)) {
- value = QLockFilePrivate::checkFcntlWorksAfterFlock();
- fcntlOK.store(value);
+ QMutexLocker lock(&fcntlLock);
+ bool *worksPtr = fcntlOK->object(fn);
+ if (!worksPtr) {
+ worksPtr = new bool(QLockFilePrivate::checkFcntlWorksAfterFlock(fn));
+ fcntlOK->insert(fn, worksPtr);
}
- return value == 1;
+
+ return *worksPtr;
}
-static bool setNativeLocks(int fd)
+static bool setNativeLocks(const QString &fileName, int fd)
{
#if defined(LOCK_EX) && defined(LOCK_NB)
if (flock(fd, LOCK_EX | LOCK_NB) == -1) // other threads, and other processes on a local fs
@@ -154,8 +168,10 @@ static bool setNativeLocks(int fd)
flockData.l_start = 0;
flockData.l_len = 0; // 0 = entire file
flockData.l_pid = getpid();
- if (fcntlWorksAfterFlock() && fcntl(fd, F_SETLK, &flockData) == -1) // for networked filesystems
+ if (fcntlWorksAfterFlock(QDir::cleanPath(QFileInfo(fileName).absolutePath()) + QString('/'))
+ && fcntl(fd, F_SETLK, &flockData) == -1) { // for networked filesystems
return false;
+ }
return true;
}
@@ -182,7 +198,7 @@ QLockFile::LockError QLockFilePrivate::tryLock_sys()
}
}
// Ensure nobody else can delete the file while we have it
- if (!setNativeLocks(fd)) {
+ if (!setNativeLocks(fileName, fd)) {
const int errnoSaved = errno;
qWarning() << "setNativeLocks failed:" << qt_error_string(errnoSaved);
}
@@ -213,7 +229,7 @@ bool QLockFilePrivate::removeStaleLock()
const int fd = qt_safe_open(lockFileName.constData(), O_WRONLY, 0644);
if (fd < 0) // gone already?
return false;
- bool success = setNativeLocks(fd) && (::unlink(lockFileName) == 0);
+ bool success = setNativeLocks(fileName, fd) && (::unlink(lockFileName) == 0);
close(fd);
return success;
}
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 956207961c..dcbd69c5e5 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -1408,13 +1408,17 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
Concurrent read and write are not a problem because the writing operation is atomic.
*/
QLockFile lockFile(confFile->name + QLatin1String(".lock"));
+#endif
if (!readOnly) {
- if (!confFile->isWritable() || !lockFile.lock() ) {
+ if (!confFile->isWritable()
+#ifndef QT_BOOTSTRAPPED
+ || !lockFile.lock()
+#endif
+ ) {
setStatus(QSettings::AccessError);
return;
}
}
-#endif
/*
We hold the lock. Let's reread the file if it has changed
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index e88024661d..ed119f61b6 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -562,6 +562,7 @@ public:
inline bool hasFragment() const { return sectionIsPresent & Fragment; }
inline bool isLocalFile() const { return flags & IsLocalFile; }
+ QString toLocalFile(QUrl::FormattingOptions options) const;
QString mergePaths(const QString &relativePath) const;
@@ -1466,6 +1467,33 @@ inline void QUrlPrivate::parse(const QString &url, QUrl::ParsingMode parsingMode
validateComponent(Fragment, url, hash + 1, len);
}
+QString QUrlPrivate::toLocalFile(QUrl::FormattingOptions options) const
+{
+ QString tmp;
+ QString ourPath;
+ appendPath(ourPath, options, QUrlPrivate::Path);
+
+ // magic for shared drive on windows
+ if (!host.isEmpty()) {
+ tmp = QStringLiteral("//") + host;
+#ifdef Q_OS_WIN // QTBUG-42346, WebDAV is visible as local file on Windows only.
+ if (scheme == webDavScheme())
+ tmp += webDavSslTag();
+#endif
+ if (!ourPath.isEmpty() && !ourPath.startsWith(QLatin1Char('/')))
+ tmp += QLatin1Char('/');
+ tmp += ourPath;
+ } else {
+ tmp = ourPath;
+#ifdef Q_OS_WIN
+ // magic for drives on windows
+ if (ourPath.length() > 2 && ourPath.at(0) == QLatin1Char('/') && ourPath.at(2) == QLatin1Char(':'))
+ tmp.remove(0, 1);
+#endif
+ }
+ return tmp;
+}
+
/*
From http://www.ietf.org/rfc/rfc3986.txt, 5.2.3: Merge paths
@@ -3263,7 +3291,7 @@ QString QUrl::toString(FormattingOptions options) const
&& (!d->hasQuery() || options.testFlag(QUrl::RemoveQuery))
&& (!d->hasFragment() || options.testFlag(QUrl::RemoveFragment))
&& isLocalFile()) {
- return path(options);
+ return d->toLocalFile(options);
}
QString url;
@@ -3826,28 +3854,7 @@ QString QUrl::toLocalFile() const
if (!isLocalFile())
return QString();
- QString tmp;
- QString ourPath = path(QUrl::FullyDecoded);
-
- // magic for shared drive on windows
- if (!d->host.isEmpty()) {
- tmp = QStringLiteral("//") + host();
-#ifdef Q_OS_WIN // QTBUG-42346, WebDAV is visible as local file on Windows only.
- if (scheme() == webDavScheme())
- tmp += webDavSslTag();
-#endif
- if (!ourPath.isEmpty() && !ourPath.startsWith(QLatin1Char('/')))
- tmp += QLatin1Char('/');
- tmp += ourPath;
- } else {
- tmp = ourPath;
-#ifdef Q_OS_WIN
- // magic for drives on windows
- if (ourPath.length() > 2 && ourPath.at(0) == QLatin1Char('/') && ourPath.at(2) == QLatin1Char(':'))
- tmp.remove(0, 1);
-#endif
- }
- return tmp;
+ return d->toLocalFile(QUrl::FullyDecoded);
}
/*!
diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp
index 7c27a85e3e..3f599e464f 100644
--- a/src/corelib/io/qwinoverlappedionotifier.cpp
+++ b/src/corelib/io/qwinoverlappedionotifier.cpp
@@ -370,7 +370,7 @@ bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped
return false;
if (triggeredOverlapped == overlapped)
return true;
- msecs = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
+ t = qt_subtract_from_timeout(msecs, stopWatch.elapsed());
if (t == 0)
return false;
}
diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h
index 9adb4b06e3..770f2c3785 100644
--- a/src/corelib/json/qjson_p.h
+++ b/src/corelib/json/qjson_p.h
@@ -311,7 +311,7 @@ public:
{
d->length = str.length();
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- const qle_ushort *uc = (const qle_ushort *)str.unicode();
+ const ushort *uc = (const ushort *)str.unicode();
for (int i = 0; i < str.length(); ++i)
d->utf16[i] = uc[i];
#else
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 12296a3bec..d3242b6e67 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -84,6 +84,7 @@ extern uint qGlobalPostedEventsCount();
enum {
WM_QT_SOCKETNOTIFIER = WM_USER,
WM_QT_SENDPOSTEDEVENTS = WM_USER + 1,
+ WM_QT_ACTIVATENOTIFIERS = WM_USER + 2,
SendPostedEventsWindowsTimerId = ~1u
};
@@ -314,7 +315,7 @@ static void resolveTimerAPI()
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
: threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0),
getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0),
- wakeUps(0)
+ wakeUps(0), activateNotifiersPosted(false)
{
resolveTimerAPI();
}
@@ -398,6 +399,7 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
if (sn) {
d->doWsaAsyncSelect(sn->fd, 0);
d->active_fd[sn->fd].selected = false;
+ d->postActivateSocketNotifiers();
if (type < 3) {
QEvent event(QEvent::SockAct);
QCoreApplication::sendEvent(sn->obj, &event);
@@ -408,6 +410,20 @@ LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPA
}
}
return 0;
+ } else if (message == WM_QT_ACTIVATENOTIFIERS) {
+ Q_ASSERT(d != 0);
+
+ // register all socket notifiers
+ for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end();
+ it != end; ++it) {
+ QSockFd &sd = it.value();
+ if (!sd.selected) {
+ d->doWsaAsyncSelect(it.key(), sd.event);
+ sd.selected = true;
+ }
+ }
+ d->activateNotifiersPosted = false;
+ return 0;
} else if (message == WM_QT_SENDPOSTEDEVENTS
// we also use a Windows timer to send posted events when the message queue is full
|| (message == WM_TIMER
@@ -648,6 +664,12 @@ void QEventDispatcherWin32Private::doWsaAsyncSelect(int socket, long event)
WSAAsyncSelect(socket, internalHwnd, event ? int(WM_QT_SOCKETNOTIFIER) : 0, event);
}
+void QEventDispatcherWin32Private::postActivateSocketNotifiers()
+{
+ if (!activateNotifiersPosted)
+ activateNotifiersPosted = PostMessage(internalHwnd, WM_QT_ACTIVATENOTIFIERS, 0, 0);
+}
+
void QEventDispatcherWin32::createInternalHwnd()
{
Q_D(QEventDispatcherWin32);
@@ -766,16 +788,6 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
d->queuedSocketEvents.append(msg);
continue;
}
- } else if (!(flags & QEventLoop::ExcludeSocketNotifiers)) {
- // register all socket notifiers
- for (QSFDict::iterator it = d->active_fd.begin(), end = d->active_fd.end();
- it != end; ++it) {
- QSockFd &sd = it.value();
- if (!sd.selected) {
- d->doWsaAsyncSelect(it.key(), sd.event);
- sd.selected = true;
- }
- }
}
}
if (!haveMessage) {
@@ -896,6 +908,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
"same socket %d and type %s", sockfd, t[type]);
}
+ createInternalHwnd();
+
QSockNot *sn = new QSockNot;
sn->obj = notifier;
sn->fd = sockfd;
@@ -920,6 +934,8 @@ void QEventDispatcherWin32::registerSocketNotifier(QSocketNotifier *notifier)
} else {
d->active_fd.insert(sockfd, QSockFd(event));
}
+
+ d->postActivateSocketNotifiers();
}
void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
@@ -945,10 +961,12 @@ void QEventDispatcherWin32::unregisterSocketNotifier(QSocketNotifier *notifier)
d->doWsaAsyncSelect(sockfd, 0);
const long event[3] = { FD_READ | FD_CLOSE | FD_ACCEPT, FD_WRITE | FD_CONNECT, FD_OOB };
sd.event ^= event[type];
- if (sd.event == 0)
+ if (sd.event == 0) {
d->active_fd.erase(it);
- else
+ } else if (sd.selected) {
sd.selected = false;
+ d->postActivateSocketNotifiers();
+ }
}
QSNDict *sn_vec[3] = { &d->sn_read, &d->sn_write, &d->sn_except };
diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h
index 6efa81fe79..848dbaf475 100644
--- a/src/corelib/kernel/qeventdispatcher_win_p.h
+++ b/src/corelib/kernel/qeventdispatcher_win_p.h
@@ -184,7 +184,9 @@ public:
QSNDict sn_write;
QSNDict sn_except;
QSFDict active_fd;
+ bool activateNotifiersPosted;
void doWsaAsyncSelect(int socket, long event);
+ void postActivateSocketNotifiers();
QList<QWinEventNotifier *> winEventNotifierList;
void activateEventNotifier(QWinEventNotifier * wen);
diff --git a/src/corelib/kernel/qsignalmapper.cpp b/src/corelib/kernel/qsignalmapper.cpp
index c738866d61..a483717da5 100644
--- a/src/corelib/kernel/qsignalmapper.cpp
+++ b/src/corelib/kernel/qsignalmapper.cpp
@@ -226,6 +226,9 @@ QObject *QSignalMapper::mapping(QObject *object) const
Removes all mappings for \a sender.
This is done automatically when mapped objects are destroyed.
+
+ \note This does not disconnect any signals. If \a sender is not destroyed
+ then this will need to be done explicitly if required.
*/
void QSignalMapper::removeMappings(QObject *sender)
{
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index 143da62b63..01351f97ff 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -2886,6 +2886,7 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
/*QUuid*/ 1 << QVariant::String
};
+static const size_t qCanConvertMatrixMaximumTargetType = 8 * sizeof(*qCanConvertMatrix);
#ifndef QT_BOOTSTRAPPED
/*!
@@ -3135,8 +3136,9 @@ bool QVariant::canConvert(int targetTypeId) const
case QMetaType::ULong:
case QMetaType::Short:
case QMetaType::UShort:
- return qCanConvertMatrix[QVariant::Int] & (1 << currentType)
- || currentType == QVariant::Int
+ return currentType == QVariant::Int
+ || (currentType < qCanConvertMatrixMaximumTargetType
+ && qCanConvertMatrix[QVariant::Int] & (1U << currentType))
|| QMetaType::typeFlags(currentType) & QMetaType::IsEnumeration;
case QMetaType::QObjectStar:
return canConvertMetaObject(currentType, targetTypeId, d.data.o);
@@ -3147,7 +3149,8 @@ bool QVariant::canConvert(int targetTypeId) const
if (targetTypeId == String && currentType == StringList)
return v_cast<QStringList>(&d)->count() == 1;
- return qCanConvertMatrix[targetTypeId] & (1 << currentType);
+ return currentType < qCanConvertMatrixMaximumTargetType
+ && qCanConvertMatrix[targetTypeId] & (1U << currentType);
}
/*!
diff --git a/src/corelib/kernel/qvariant_p.h b/src/corelib/kernel/qvariant_p.h
index 4d1f883651..d01f386032 100644
--- a/src/corelib/kernel/qvariant_p.h
+++ b/src/corelib/kernel/qvariant_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2016 Intel Corporation.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -65,6 +66,7 @@ struct QVariantIntegrator
{
static const bool CanUseInternalSpace = sizeof(T) <= sizeof(QVariant::Private::Data)
&& ((QTypeInfoQuery<T>::isRelocatable) || Q_IS_ENUM(T));
+ typedef QtPrivate::integral_constant<bool, CanUseInternalSpace> CanUseInternalSpace_t;
};
Q_STATIC_ASSERT(QVariantIntegrator<double>::CanUseInternalSpace);
Q_STATIC_ASSERT(QVariantIntegrator<long int>::CanUseInternalSpace);
@@ -115,31 +117,49 @@ private:
T m_t;
};
-// constructs a new variant if copy is 0, otherwise copy-constructs
template <class T>
-inline void v_construct(QVariant::Private *x, const void *copy, T * = 0)
+inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::true_type)
{
- if (!QVariantIntegrator<T>::CanUseInternalSpace) {
- x->data.shared = copy ? new QVariantPrivateSharedEx<T>(*static_cast<const T *>(copy))
- : new QVariantPrivateSharedEx<T>;
- x->is_shared = true;
- } else {
- if (copy)
- new (&x->data.ptr) T(*static_cast<const T *>(copy));
- else
- new (&x->data.ptr) T;
- }
+ new (&x->data) T(t);
+ x->is_shared = false;
+}
+
+template <class T>
+inline void v_construct_helper(QVariant::Private *x, const T &t, QtPrivate::false_type)
+{
+ x->data.shared = new QVariantPrivateSharedEx<T>(t);
+ x->is_shared = true;
+}
+
+template <class T>
+inline void v_construct_helper(QVariant::Private *x, QtPrivate::true_type)
+{
+ new (&x->data) T();
+ x->is_shared = false;
+}
+
+template <class T>
+inline void v_construct_helper(QVariant::Private *x, QtPrivate::false_type)
+{
+ x->data.shared = new QVariantPrivateSharedEx<T>;
+ x->is_shared = true;
}
template <class T>
inline void v_construct(QVariant::Private *x, const T &t)
{
- if (!QVariantIntegrator<T>::CanUseInternalSpace) {
- x->data.shared = new QVariantPrivateSharedEx<T>(t);
- x->is_shared = true;
- } else {
- new (&x->data.ptr) T(t);
- }
+ // dispatch
+ v_construct_helper(x, t, typename QVariantIntegrator<T>::CanUseInternalSpace_t());
+}
+
+// constructs a new variant if copy is 0, otherwise copy-constructs
+template <class T>
+inline void v_construct(QVariant::Private *x, const void *copy, T * = 0)
+{
+ if (copy)
+ v_construct<T>(x, *static_cast<const T *>(copy));
+ else
+ v_construct_helper<T>(x, typename QVariantIntegrator<T>::CanUseInternalSpace_t());
}
// deletes the internal structures
@@ -294,39 +314,11 @@ protected:
template<class Filter>
class QVariantConstructor
{
- template<typename T, bool CanUseInternalSpace = QVariantIntegrator<T>::CanUseInternalSpace>
- struct CallConstructor {};
-
- template<typename T>
- struct CallConstructor<T, /* CanUseInternalSpace = */ true>
- {
- CallConstructor(const QVariantConstructor &tc)
- {
- if (tc.m_copy)
- new (&tc.m_x->data.ptr) T(*static_cast<const T*>(tc.m_copy));
- else
- new (&tc.m_x->data.ptr) T();
- tc.m_x->is_shared = false;
- }
- };
-
- template<typename T>
- struct CallConstructor<T, /* CanUseInternalSpace = */ false>
- {
- CallConstructor(const QVariantConstructor &tc)
- {
- Q_STATIC_ASSERT(QTypeInfo<T>::isComplex || sizeof(T) > sizeof(QVariant::Private::Data));
- tc.m_x->data.shared = tc.m_copy ? new QVariantPrivateSharedEx<T>(*static_cast<const T*>(tc.m_copy))
- : new QVariantPrivateSharedEx<T>;
- tc.m_x->is_shared = true;
- }
- };
-
template<typename T, bool IsAcceptedType = Filter::template Acceptor<T>::IsAccepted>
struct FilteredConstructor {
FilteredConstructor(const QVariantConstructor &tc)
{
- CallConstructor<T> tmp(tc);
+ v_construct<T>(tc.m_x, tc.m_copy);
tc.m_x->is_null = !tc.m_copy;
}
};
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 7c70a99baf..62a4c03d26 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -1894,12 +1894,14 @@ void QStateMachinePrivate::_q_process()
}
}
if (enabledTransitions.isEmpty()) {
- processing = false;
- stopProcessingReason = EventQueueEmpty;
- noMicrostep();
+ if (isInternalEventQueueEmpty()) {
+ processing = false;
+ stopProcessingReason = EventQueueEmpty;
+ noMicrostep();
#ifdef QSTATEMACHINE_DEBUG
- qDebug() << q << ": no transitions enabled";
+ qDebug() << q << ": no transitions enabled";
#endif
+ }
} else {
didChange = true;
q->beginMicrostep(e);
diff --git a/src/corelib/thread/qexception.cpp b/src/corelib/thread/qexception.cpp
index e45e6f4895..62c2b608d8 100644
--- a/src/corelib/thread/qexception.cpp
+++ b/src/corelib/thread/qexception.cpp
@@ -171,7 +171,7 @@ public:
};
ExceptionHolder::ExceptionHolder(QException *exception)
-: base(new Base(exception)) {}
+: base(exception ? new Base(exception) : Q_NULLPTR) {}
ExceptionHolder::ExceptionHolder(const ExceptionHolder &other)
: base(other.base)
@@ -187,6 +187,8 @@ ExceptionHolder::~ExceptionHolder()
QException *ExceptionHolder::exception() const
{
+ if (!base)
+ return Q_NULLPTR;
return base->exception;
}
diff --git a/src/corelib/thread/qexception.h b/src/corelib/thread/qexception.h
index 329b5610de..b14d386c69 100644
--- a/src/corelib/thread/qexception.h
+++ b/src/corelib/thread/qexception.h
@@ -92,7 +92,7 @@ class Q_CORE_EXPORT ExceptionHolder
public:
ExceptionHolder(QException *exception = Q_NULLPTR);
ExceptionHolder(const ExceptionHolder &other);
- void operator=(const ExceptionHolder &other);
+ void operator=(const ExceptionHolder &other); // ### Qt6: copy-assign operator shouldn't return void. Remove this method and the copy-ctor, they are unneeded.
~ExceptionHolder();
QException *exception() const;
QExplicitlySharedDataPointer<Base> base;
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index fbe9a15d98..f54f7c705d 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -53,6 +53,8 @@
#include <QtCore/qmutex.h>
+#include <functional>
+
QT_BEGIN_NAMESPACE
/*
@@ -63,8 +65,8 @@ class QOrderedMutexLocker
{
public:
QOrderedMutexLocker(QMutex *m1, QMutex *m2)
- : mtx1((m1 == m2) ? m1 : (m1 < m2 ? m1 : m2)),
- mtx2((m1 == m2) ? 0 : (m1 < m2 ? m2 : m1)),
+ : mtx1((m1 == m2) ? m1 : (std::less<QMutex *>()(m1, m2) ? m1 : m2)),
+ mtx2((m1 == m2) ? 0 : (std::less<QMutex *>()(m1, m2) ? m2 : m1)),
locked(false)
{
relock();
diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp
index afe53d6558..ae83943b7e 100644
--- a/src/corelib/tools/qdatetime.cpp
+++ b/src/corelib/tools/qdatetime.cpp
@@ -98,14 +98,25 @@ static inline QDate fixedDate(int y, int m, int d)
return result;
}
+/*
+ Until C++11, rounding direction is implementation-defined.
+
+ For negative operands, implementations may chose to round down instead of
+ towards zero (truncation). We only actually care about the case a < 0, as all
+ uses of floordiv have b > 0. In this case, if rounding is down we have a % b
+ >= 0 and simple division works fine; but a % b = a - (a / b) * b always, so
+ rounding towards zero gives a % b <= 0; when < 0, we need to adjust.
+
+ Once we assume C++11, we can safely test a < 0 instead of a % b < 0.
+ */
static inline qint64 floordiv(qint64 a, int b)
{
- return (a - (a < 0 ? b-1 : 0)) / b;
+ return (a - (a % b < 0 ? b - 1 : 0)) / b;
}
static inline int floordiv(int a, int b)
{
- return (a - (a < 0 ? b-1 : 0)) / b;
+ return (a - (a % b < 0 ? b - 1 : 0)) / b;
}
static inline qint64 julianDayFromDate(int year, int month, int day)
@@ -3660,6 +3671,40 @@ QString QDateTime::toString(const QString& format) const
}
#endif //QT_NO_DATESTRING
+static void massageAdjustedDateTime(Qt::TimeSpec spec,
+#ifndef QT_BOOTSTRAPPED
+ const QTimeZone &zone,
+#endif // QT_BOOTSTRAPPED
+ QDate *date,
+ QTime *time)
+{
+ /*
+ If we have just adjusted to a day with a DST transition, our given time
+ may lie in the transition hour (either missing or duplicated). For any
+ other time, telling mktime (deep in the bowels of localMSecsToEpochMSecs)
+ we don't know its DST-ness will produce no adjustment (just a decision as
+ to its DST-ness); but for a time in spring's missing hour it'll adjust the
+ time while picking a DST-ness. (Handling of autumn is trickier, as either
+ DST-ness is valid, without adjusting the time. We might want to propagate
+ d->daylightStatus() in that case, but it's hard to do so without breaking
+ (far more common) other cases; and it makes little difference, as the two
+ answers do then differ only in DST-ness.)
+ */
+ if (spec == Qt::LocalTime) {
+ QDateTimePrivate::DaylightStatus status = QDateTimePrivate::UnknownDaylightTime;
+ localMSecsToEpochMSecs(timeToMSecs(*date, *time), &status, date, time);
+#ifndef QT_BOOTSTRAPPED
+ } else if (spec == Qt::TimeZone) {
+ QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(*date, *time), zone, date, time);
+#endif // QT_BOOTSTRAPPED
+ }
+}
+#ifdef QT_BOOTSTRAPPED // Avoid duplicate #if-ery in uses.
+#define MASSAGEADJUSTEDDATETIME(s, z, d, t) massageAdjustedDateTime(s, d, t)
+#else
+#define MASSAGEADJUSTEDDATETIME(s, z, d, t) massageAdjustedDateTime(s, z, d, t)
+#endif // QT_BOOTSTRAPPED
+
/*!
Returns a QDateTime object containing a datetime \a ndays days
later than the datetime of this object (or earlier if \a ndays is
@@ -3681,16 +3726,7 @@ QDateTime QDateTime::addDays(qint64 ndays) const
QDate &date = p.first;
QTime &time = p.second;
date = date.addDays(ndays);
- // Result might fall into "missing" DaylightTime transition hour,
- // so call conversion and use the adjusted returned time
- if (d->m_spec == Qt::LocalTime) {
- QDateTimePrivate::DaylightStatus status = d->daylightStatus();
- localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time);
-#ifndef QT_BOOTSTRAPPED
- } else if (d->m_spec == Qt::TimeZone) {
- QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time);
-#endif // QT_BOOTSTRAPPED
- }
+ MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time);
dt.d->setDateTime(date, time);
return dt;
}
@@ -3716,16 +3752,7 @@ QDateTime QDateTime::addMonths(int nmonths) const
QDate &date = p.first;
QTime &time = p.second;
date = date.addMonths(nmonths);
- // Result might fall into "missing" DaylightTime transition hour,
- // so call conversion and use the adjusted returned time
- if (d->m_spec == Qt::LocalTime) {
- QDateTimePrivate::DaylightStatus status = d->daylightStatus();
- localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time);
-#ifndef QT_BOOTSTRAPPED
- } else if (d->m_spec == Qt::TimeZone) {
- QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time);
-#endif // QT_BOOTSTRAPPED
- }
+ MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time);
dt.d->setDateTime(date, time);
return dt;
}
@@ -3751,19 +3778,11 @@ QDateTime QDateTime::addYears(int nyears) const
QDate &date = p.first;
QTime &time = p.second;
date = date.addYears(nyears);
- // Result might fall into "missing" DaylightTime transition hour,
- // so call conversion and use the adjusted returned time
- if (d->m_spec == Qt::LocalTime) {
- QDateTimePrivate::DaylightStatus status = d->daylightStatus();
- localMSecsToEpochMSecs(timeToMSecs(date, time), &status, &date, &time);
-#ifndef QT_BOOTSTRAPPED
- } else if (d->m_spec == Qt::TimeZone) {
- QDateTimePrivate::zoneMSecsToEpochMSecs(timeToMSecs(date, time), d->m_timeZone, &date, &time);
-#endif // QT_BOOTSTRAPPED
- }
+ MASSAGEADJUSTEDDATETIME(d->m_spec, d->m_timeZone, &date, &time);
dt.d->setDateTime(date, time);
return dt;
}
+#undef MASSAGEADJUSTEDDATETIME
/*!
Returns a QDateTime object containing a datetime \a s seconds
diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp
index 5ba1ca61d1..ace663ae30 100644
--- a/src/corelib/tools/qdatetimeparser.cpp
+++ b/src/corelib/tools/qdatetimeparser.cpp
@@ -388,7 +388,7 @@ bool QDateTimeParser::parseFormat(const QString &newFormat)
++add;
if (status != quote) {
status = quote;
- } else if (newFormat.at(i - 1) != slash) {
+ } else if (i > 0 && newFormat.at(i - 1) != slash) {
status = zero;
}
} else if (status != quote) {
@@ -500,15 +500,15 @@ bool QDateTimeParser::parseFormat(const QString &newFormat)
}
if ((newDisplay & (AmPmSection|Hour12Section)) == Hour12Section) {
- const int max = newSectionNodes.size();
- for (int i=0; i<max; ++i) {
+ const int count = newSectionNodes.size();
+ for (int i = 0; i < count; ++i) {
SectionNode &node = newSectionNodes[i];
if (node.type == Hour12Section)
node.type = Hour24Section;
}
}
- if (index < newFormat.size()) {
+ if (index < max) {
appendSeparator(&newSeparators, newFormat, index, index - max, lastQuote);
} else {
newSeparators.append(QString());
@@ -771,8 +771,8 @@ int QDateTimeParser::parseSection(const QDateTime &currentValue, int sectionInde
} else {
state = Intermediate;
}
- break; }
- // fall through
+ break;
+ } // else: fall through
case DaySection:
case YearSection:
case YearSection2Digits:
@@ -895,17 +895,17 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos
QDTPDEBUG << "parse" << input;
{
- int year, month, day, hour12, hour, minute, second, msec, ampm, dayofweek, year2digits;
+ int year, month, day;
currentValue.date().getDate(&year, &month, &day);
- year2digits = year % 100;
- hour = currentValue.time().hour();
- hour12 = -1;
- minute = currentValue.time().minute();
- second = currentValue.time().second();
- msec = currentValue.time().msec();
- dayofweek = currentValue.date().dayOfWeek();
-
- ampm = -1;
+ int year2digits = year % 100;
+ int hour = currentValue.time().hour();
+ int hour12 = -1;
+ int minute = currentValue.time().minute();
+ int second = currentValue.time().second();
+ int msec = currentValue.time().msec();
+ int dayofweek = currentValue.date().dayOfWeek();
+
+ int ampm = -1;
Sections isSet = NoSection;
int num;
State tmpstate;
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 7d3ffe0b0b..90d2f99943 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -122,6 +122,13 @@ QLocale::Language QLocalePrivate::codeToLanguage(const QString &code)
Q_STATIC_ASSERT(QLocale::Moldavian == QLocale::Romanian);
return QLocale::Moldavian;
}
+ // Android uses the following deprecated codes
+ if (uc1 == 'i' && uc2 == 'w' && uc3 == 0) // iw -> he
+ return QLocale::Hebrew;
+ if (uc1 == 'i' && uc2 == 'n' && uc3 == 0) // in -> id
+ return QLocale::Indonesian;
+ if (uc1 == 'j' && uc2 == 'i' && uc3 == 0) // ji -> yi
+ return QLocale::Yiddish;
return QLocale::C;
}
diff --git a/src/corelib/tools/qsharedpointer.h b/src/corelib/tools/qsharedpointer.h
index 67183da778..901862e7a2 100644
--- a/src/corelib/tools/qsharedpointer.h
+++ b/src/corelib/tools/qsharedpointer.h
@@ -114,11 +114,11 @@ public:
~QWeakPointer();
- QWeakPointer<T> operator=(const QWeakPointer<T> &other);
- QWeakPointer<T> operator=(const QSharedPointer<T> &other);
+ QWeakPointer<T> &operator=(const QWeakPointer<T> &other);
+ QWeakPointer<T> &operator=(const QSharedPointer<T> &other);
QWeakPointer(const QObject *other);
- QWeakPointer<T> operator=(const QObject *other);
+ QWeakPointer<T> &operator=(const QObject *other);
void swap(QWeakPointer<T> &other);
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 21fdf9e252..0e3b1f2f82 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -92,7 +92,7 @@ public:
Q_DECL_CONSTEXPR inline QLatin1String() Q_DECL_NOTHROW : m_size(0), m_data(Q_NULLPTR) {}
Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s) Q_DECL_NOTHROW : m_size(s ? int(strlen(s)) : 0), m_data(s) {}
Q_DECL_CONSTEXPR inline explicit QLatin1String(const char *s, int sz) Q_DECL_NOTHROW : m_size(sz), m_data(s) {}
- inline explicit QLatin1String(const QByteArray &s) Q_DECL_NOTHROW : m_size(s.size()), m_data(s.constData()) {}
+ inline explicit QLatin1String(const QByteArray &s) Q_DECL_NOTHROW : m_size(int(qstrnlen(s.constData(), s.size()))), m_data(s.constData()) {}
Q_DECL_CONSTEXPR const char *latin1() const Q_DECL_NOTHROW { return m_data; }
Q_DECL_CONSTEXPR int size() const Q_DECL_NOTHROW { return m_size; }
@@ -546,11 +546,11 @@ public:
return fromLocal8Bit_helper(str, (str && size == -1) ? int(strlen(str)) : size);
}
static inline QString fromLatin1(const QByteArray &str)
- { return str.isNull() ? QString() : fromLatin1(str.data(), str.size()); }
+ { return str.isNull() ? QString() : fromLatin1(str.data(), qstrnlen(str.constData(), str.size())); }
static inline QString fromUtf8(const QByteArray &str)
- { return str.isNull() ? QString() : fromUtf8(str.data(), str.size()); }
+ { return str.isNull() ? QString() : fromUtf8(str.data(), qstrnlen(str.constData(), str.size())); }
static inline QString fromLocal8Bit(const QByteArray &str)
- { return str.isNull() ? QString() : fromLocal8Bit(str.data(), str.size()); }
+ { return str.isNull() ? QString() : fromLocal8Bit(str.data(), qstrnlen(str.constData(), str.size())); }
static QString fromUtf16(const ushort *, int size = -1);
static QString fromUcs4(const uint *, int size = -1);
static QString fromRawData(const QChar *, int size);
@@ -663,7 +663,7 @@ public:
: d(fromAscii_helper(ch, ch ? int(strlen(ch)) : -1))
{}
inline QT_ASCII_CAST_WARN QString(const QByteArray &a)
- : d(fromAscii_helper(a.constData(), a.size()))
+ : d(fromAscii_helper(a.constData(), qstrnlen(a.constData(), a.size())))
{}
inline QT_ASCII_CAST_WARN QString &operator=(const char *ch)
{ return (*this = fromUtf8(ch)); }
@@ -1232,9 +1232,9 @@ inline QT_ASCII_CAST_WARN bool QLatin1String::operator>=(const QByteArray &s) co
{ return QString::fromUtf8(s) <= *this; }
inline QT_ASCII_CAST_WARN bool QString::operator==(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) == 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) == 0; }
inline QT_ASCII_CAST_WARN bool QString::operator!=(const QByteArray &s) const
-{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) != 0; }
+{ return QString::compare_helper(constData(), size(), s.constData(), qstrnlen(s.constData(), s.size())) != 0; }
inline QT_ASCII_CAST_WARN bool QString::operator<(const QByteArray &s) const
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) < 0; }
inline QT_ASCII_CAST_WARN bool QString::operator>(const QByteArray &s) const
@@ -1245,9 +1245,9 @@ inline QT_ASCII_CAST_WARN bool QString::operator>=(const QByteArray &s) const
{ return QString::compare_helper(constData(), size(), s.constData(), s.size()) >= 0; }
inline bool QByteArray::operator==(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) == 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) == 0; }
inline bool QByteArray::operator!=(const QString &s) const
-{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) != 0; }
+{ return QString::compare_helper(s.constData(), s.size(), constData(), qstrnlen(constData(), size())) != 0; }
inline bool QByteArray::operator<(const QString &s) const
{ return QString::compare_helper(s.constData(), s.size(), constData(), size()) > 0; }
inline bool QByteArray::operator>(const QString &s) const