From 8c2f0ac3827e765dfd31711ad576b396df7df467 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 20 Sep 2014 18:52:15 +0200 Subject: QObject: fix a memory leak in moveToThread For some reason it seems to be supported to call moveToThread(0). That call will allocate a new QThreadData for the object. However, if we then detect that we're calling moveToThread from a thread which is not the one the QObject has affinity with, we error out leaking that QThreadData object. Change-Id: I0fe6625a2a9887535e457f3897b514d2a03d1480 Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz --- src/corelib/kernel/qobject.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index e588808ee8..9ab952362c 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1461,14 +1461,14 @@ void QObject::moveToThread(QThread *targetThread) } QThreadData *currentData = QThreadData::current(); - QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : new QThreadData(0); + QThreadData *targetData = targetThread ? QThreadData::get2(targetThread) : Q_NULLPTR; if (d->threadData->thread == 0 && currentData == targetData) { // one exception to the rule: we allow moving objects with no thread affinity to the current thread currentData = d->threadData; } else if (d->threadData != currentData) { qWarning("QObject::moveToThread: Current thread (%p) is not the object's thread (%p).\n" "Cannot move to target thread (%p)\n", - currentData->thread, d->threadData->thread, targetData->thread); + currentData->thread, d->threadData->thread, targetData ? targetData->thread : Q_NULLPTR); #ifdef Q_OS_MAC qWarning("On Mac OS X, you might be loading two sets of Qt binaries into the same process. " @@ -1482,6 +1482,9 @@ void QObject::moveToThread(QThread *targetThread) // prepare to move d->moveToThread_helper(); + if (!targetData) + targetData = new QThreadData(0); + QOrderedMutexLocker locker(¤tData->postEventList.mutex, &targetData->postEventList.mutex); -- cgit v1.2.3 From bc5a1c6d3fc36d9d48c719895c2061e052ead17e Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sat, 20 Sep 2014 16:49:24 +0200 Subject: QFile: fix undefined behavior when closing a buffered file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C11 ยง7.21.3.4 [Files] says that The value of a pointer to a FILE object is indeterminate after the associated file is closed POSIX.1-2013 reinforces by saying that After the call to fclose(), any use of stream results in undefined behavior. This means we can't call fclose() again on a FILE *, even if fclose() returned EOF and set errno to EINTR. Change-Id: I282f4ff926e3c134729defa290c80d42431e97ce Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qfsfileengine.cpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 1ae182a4c1..e198cd6d75 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -168,10 +168,7 @@ QFSFileEngine::~QFSFileEngine() Q_D(QFSFileEngine); if (d->closeFileHandle) { if (d->fh) { - int ret; - do { - ret = fclose(d->fh); - } while (ret == EOF && errno == EINTR); + fclose(d->fh); } else if (d->fd != -1) { int ret; do { @@ -375,15 +372,14 @@ bool QFSFileEnginePrivate::closeFdFh() // Close the file if we created the handle. if (closeFileHandle) { int ret; - do { - if (fh) { - // Close buffered file. - ret = fclose(fh) != 0 ? -1 : 0; - } else { - // Close unbuffered file. - ret = QT_CLOSE(fd); - } - } while (ret == -1 && errno == EINTR); + + if (fh) { + // Close buffered file. + ret = fclose(fh); + } else { + // Close unbuffered file. + EINTR_LOOP(ret, QT_CLOSE(fd)); + } // We must reset these guys regardless; calling close again after a // failed close causes crashes on some systems. -- cgit v1.2.3 From 0d48e774c6361d91dff9bd65785b1043ef20ea25 Mon Sep 17 00:00:00 2001 From: Giuseppe D'Angelo Date: Sun, 21 Sep 2014 15:18:17 +0200 Subject: Refactor some loops over EINTR QT_CLOSE is #defined to be qt_safe_close which already performs the EINTR loop. So there's no need of doing other loops (either by hand or by the EINTR_LOOP macro). Change-Id: Icca256124def5ab5d79c2ba101c6f889c85d19da Reviewed-by: Thiago Macieira --- src/corelib/io/qfsfileengine.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index e198cd6d75..bed77678fa 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -170,10 +170,7 @@ QFSFileEngine::~QFSFileEngine() if (d->fh) { fclose(d->fh); } else if (d->fd != -1) { - int ret; - do { - ret = QT_CLOSE(d->fd); - } while (ret == -1 && errno == EINTR); + QT_CLOSE(d->fd); } } QList keys = d->maps.keys(); @@ -378,7 +375,7 @@ bool QFSFileEnginePrivate::closeFdFh() ret = fclose(fh); } else { // Close unbuffered file. - EINTR_LOOP(ret, QT_CLOSE(fd)); + ret = QT_CLOSE(fd); } // We must reset these guys regardless; calling close again after a -- cgit v1.2.3 From 3bfdacaaebfcb3299eedd6f02977b49e732cfc30 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 8 Aug 2014 12:12:06 -0300 Subject: Document that default-constructed QFuture are canceled Task-number: QTBUG-40680 Change-Id: Idee9ff75c89c8349be779b90ee9c34a899d92c0c Reviewed-by: Marc Mutz Reviewed-by: Jerome Pasion Reviewed-by: Martin Smith --- src/corelib/thread/qfuture.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/thread/qfuture.qdoc b/src/corelib/thread/qfuture.qdoc index 951b369fad..6b3a635291 100644 --- a/src/corelib/thread/qfuture.qdoc +++ b/src/corelib/thread/qfuture.qdoc @@ -97,7 +97,7 @@ /*! \fn QFuture::QFuture() - Constructs an empty future. + Constructs an empty, canceled future. */ /*! \fn QFuture::QFuture(const QFuture &other) -- cgit v1.2.3 From e66a878838f17a0626b0b10b340b1ca4dba56cc1 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 18 Sep 2014 13:51:29 +0200 Subject: QSettings: Don't chop off trailing tabs that were actually part of a value. This was done wrong when using the ini format. Task-number: QTBUG-22461 Change-Id: Ib9390460bce6138659cceac7e3cd25339ba5e9bb Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/io/qsettings.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 1748170324..7330a565a2 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -774,11 +774,11 @@ void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, } } -inline static void iniChopTrailingSpaces(QString &str) +inline static void iniChopTrailingSpaces(QString &str, int limit) { int n = str.size() - 1; QChar ch; - while (n >= 0 && ((ch = str.at(n)) == QLatin1Char(' ') || ch == QLatin1Char('\t'))) + while (n >= limit && ((ch = str.at(n)) == QLatin1Char(' ') || ch == QLatin1Char('\t'))) str.truncate(n--); } @@ -836,6 +836,7 @@ StSkipSpaces: // fallthrough StNormal: + int chopLimit = stringResult.length(); while (i < to) { switch (str.at(i)) { case '\\': @@ -873,6 +874,7 @@ StNormal: } else { // the character is skipped } + chopLimit = stringResult.length(); break; case '"': ++i; @@ -884,7 +886,7 @@ StNormal: case ',': if (!inQuotedString) { if (!currentValueIsQuoted) - iniChopTrailingSpaces(stringResult); + iniChopTrailingSpaces(stringResult, chopLimit); if (!isStringList) { isStringList = true; stringListResult.clear(); @@ -924,6 +926,8 @@ StNormal: } } } + if (!currentValueIsQuoted) + iniChopTrailingSpaces(stringResult, chopLimit); goto end; StHexEscape: @@ -963,8 +967,6 @@ StOctEscape: } end: - if (!currentValueIsQuoted) - iniChopTrailingSpaces(stringResult); if (isStringList) stringListResult.append(stringResult); return isStringList; -- cgit v1.2.3