From 7fd483f3de5bfb98a816e4d63724476b839effc8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sat, 25 Feb 2017 11:40:04 -0800 Subject: QDateTimeParser: Merge the code to parse names of months and weekdays Simplifies everything and avoids bugfixes in one not propagating to the other. Change-Id: I95c9e502ccc74af3bcf0fffd14a69f0cde60cc8c Reviewed-by: Edward Welbourne --- src/corelib/tools/qdatetimeparser.cpp | 136 +++++++++++++--------------------- 1 file changed, 51 insertions(+), 85 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index c8aa4fbc89..b90d7d1aea 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1243,6 +1243,34 @@ end: #endif // QT_NO_DATESTRING #ifndef QT_NO_TEXTDATE + +static int findTextEntry(const QString &text, int start, const QVector &entries, QString *usedText, int *used) +{ + if (text.isEmpty()) + return -1; + + int bestMatch = -1; + int bestCount = 0; + for (int n = start; n <= entries.size(); ++n) { + const QString name = entries.at(n - 1).toLower(); + + const int limit = qMin(text.size(), name.size()); + int i = 0; + while (i < limit && text.at(i) == name.at(i)) + ++i; + if (i > bestCount) { + bestCount = i; + bestMatch = n; + } + } + if (usedText && bestMatch != -1) + *usedText = entries.at(bestMatch - 1); + if (used) + *used = bestCount; + + return bestMatch; +} + /*! \internal finds the first possible monthname that \a str1 can @@ -1252,99 +1280,37 @@ end: int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionIndex, QString *usedMonth, int *used) const { - int bestMatch = -1; - int bestCount = 0; - if (!str1.isEmpty()) { - const SectionNode &sn = sectionNode(sectionIndex); - if (sn.type != MonthSection) { - qWarning("QDateTimeParser::findMonth Internal error"); - return -1; - } - - QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat; - QLocale l = locale(); - - for (int month=startMonth; month<=12; ++month) { - const QString monthName = l.monthName(month, type); - QString str2 = monthName.toLower(); + const SectionNode &sn = sectionNode(sectionIndex); + if (sn.type != MonthSection) { + qWarning("QDateTimeParser::findMonth Internal error"); + return -1; + } - if (str1.startsWith(str2)) { - if (used) { - QDTPDEBUG << "used is set to" << str2.size(); - *used = str2.size(); - } - if (usedMonth) - *usedMonth = monthName; + QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat; + QLocale l = locale(); + QVector monthNames; + monthNames.reserve(12); + for (int month = 1; month <= 12; ++month) + monthNames.append(month >= startMonth ? l.monthName(month, type) : QString()); - return month; - } - if (context == FromString) - continue; - - const int limit = qMin(str1.size(), str2.size()); - - QDTPDEBUG << "limit is" << limit << str1 << str2; - bool equal = true; - for (int i=0; i bestCount) { - bestCount = i; - bestMatch = month; - } - break; - } - } - if (equal) { - if (used) - *used = limit; - if (usedMonth) - *usedMonth = monthName; - return month; - } - } - if (usedMonth && bestMatch != -1) - *usedMonth = l.monthName(bestMatch, type); - } - if (used) { - QDTPDEBUG << "used is set to" << bestCount; - *used = bestCount; - } - return bestMatch; + return findTextEntry(str1, startMonth, monthNames, usedMonth, used); } int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const { - int bestMatch = -1; - int bestCount = 0; - if (!str1.isEmpty()) { - const SectionNode &sn = sectionNode(sectionIndex); - if (!(sn.type & DaySectionMask)) { - qWarning("QDateTimeParser::findDay Internal error"); - return -1; - } - const QLocale l = locale(); - for (int day=startDay; day<=7; ++day) { - const QString dayName = l.dayName(day, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat); - const QString str2 = dayName.toLower(); - - const int limit = qMin(str1.size(), str2.size()); - int i = 0; - while (i < limit && str1.at(i) == str2.at(i)) - ++i; - if (i > bestCount) { - bestCount = i; - bestMatch = day; - } - } - if (usedDay && bestMatch != -1) { - *usedDay = l.dayName(bestMatch, sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat); - } + const SectionNode &sn = sectionNode(sectionIndex); + if (!(sn.type & DaySectionMask)) { + qWarning("QDateTimeParser::findDay Internal error"); + return -1; } - if (used) - *used = bestCount; - return bestMatch; + QLocale::FormatType type = sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat; + QLocale l = locale(); + QVector daysOfWeek; + daysOfWeek.reserve(7); + for (int day = 1; day <= 7; ++day) + daysOfWeek.append(day >= startDay ? l.dayName(day, type) : QString()); + return findTextEntry(str1, startDay, daysOfWeek, usedDay, used); } #endif // QT_NO_TEXTDATE -- cgit v1.2.3 From 326f1fdb7d6550a529217b226cbef78425d32969 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 28 Feb 2017 12:03:46 +0100 Subject: Simplify QDateTimeParser's shiny new findTextEntry() Decouple from the callers' offset into a larger list; just search for an entry in a list, let the caller deal with the offset. Also, defer a .tolower() to save the need to allocate a copy of each list entry. Change-Id: I748d5214c2cc6dc592fe2bd41e3f8150f71c335b Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetimeparser.cpp | 38 +++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index b90d7d1aea..5871587f8c 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1244,19 +1244,28 @@ end: #ifndef QT_NO_TEXTDATE -static int findTextEntry(const QString &text, int start, const QVector &entries, QString *usedText, int *used) +/* + \internal + \brief Returns the index in \a entries with the best prefix match to \a text + + Scans \a entries looking for an entry overlapping \a text as much as possible. + Records the length of overlap in *used (if \a used is non-NULL) and the first + entry that overlapped this much in *usedText (if \a usedText is non-NULL). + */ +static int findTextEntry(const QString &text, const QVector &entries, QString *usedText, int *used) { if (text.isEmpty()) return -1; int bestMatch = -1; int bestCount = 0; - for (int n = start; n <= entries.size(); ++n) { - const QString name = entries.at(n - 1).toLower(); + for (int n = 0; n < entries.size(); ++n) + { + const QString &name = entries.at(n); const int limit = qMin(text.size(), name.size()); int i = 0; - while (i < limit && text.at(i) == name.at(i)) + while (i < limit && text.at(i) == name.at(i).toLower()) ++i; if (i > bestCount) { bestCount = i; @@ -1264,7 +1273,7 @@ static int findTextEntry(const QString &text, int start, const QVector } } if (usedText && bestMatch != -1) - *usedText = entries.at(bestMatch - 1); + *usedText = entries.at(bestMatch); if (used) *used = bestCount; @@ -1289,11 +1298,12 @@ int QDateTimeParser::findMonth(const QString &str1, int startMonth, int sectionI QLocale::FormatType type = sn.count == 3 ? QLocale::ShortFormat : QLocale::LongFormat; QLocale l = locale(); QVector monthNames; - monthNames.reserve(12); - for (int month = 1; month <= 12; ++month) - monthNames.append(month >= startMonth ? l.monthName(month, type) : QString()); + monthNames.reserve(13 - startMonth); + for (int month = startMonth; month <= 12; ++month) + monthNames.append(l.monthName(month, type)); - return findTextEntry(str1, startMonth, monthNames, usedMonth, used); + const int index = findTextEntry(str1, monthNames, usedMonth, used); + return index < 0 ? index : index + startMonth; } int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex, QString *usedDay, int *used) const @@ -1307,10 +1317,12 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex QLocale::FormatType type = sn.count == 4 ? QLocale::LongFormat : QLocale::ShortFormat; QLocale l = locale(); QVector daysOfWeek; - daysOfWeek.reserve(7); - for (int day = 1; day <= 7; ++day) - daysOfWeek.append(day >= startDay ? l.dayName(day, type) : QString()); - return findTextEntry(str1, startDay, daysOfWeek, usedDay, used); + daysOfWeek.reserve(8 - startDay); + for (int day = startDay; day <= 7; ++day) + daysOfWeek.append(l.dayName(day, type)); + + const int index = findTextEntry(str1, daysOfWeek, usedDay, used); + return index < 0 ? index : index + startDay; } #endif // QT_NO_TEXTDATE -- cgit v1.2.3 From 9ed389bf15787266c207435d712b9e225db07ad9 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 28 Feb 2017 12:03:46 +0100 Subject: Bugfix in QDateTimeParser's findTextEntry() If a later month-or-day were to have a name that's a prefix of an earlier one's name, the code would have selected the longer name as best match when the text matched is the shorter name, simply because it found that one first. (Found, on Turkish Cuma(rtesi)? in Thiago's recent new test, by reversing the loop that iterated the list.) Make an exact match win and a match of a full name beat any prefix match of the same length. Change-Id: I8d954b83ccc25e4f47af2e558036d714685cef5e Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetimeparser.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 5871587f8c..62dd25e072 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -1248,9 +1248,12 @@ end: \internal \brief Returns the index in \a entries with the best prefix match to \a text - Scans \a entries looking for an entry overlapping \a text as much as possible. - Records the length of overlap in *used (if \a used is non-NULL) and the first - entry that overlapped this much in *usedText (if \a usedText is non-NULL). + Scans \a entries looking for an entry overlapping \a text as much as possible + (an exact match beats any prefix match; a match of the full entry as prefix of + text beats any entry but one matching a longer prefix; otherwise, the match of + longest prefix wins, earlier entries beating later on a draw). Records the + length of overlap in *used (if \a used is non-NULL) and the first entry that + overlapped this much in *usedText (if \a usedText is non-NULL). */ static int findTextEntry(const QString &text, const QVector &entries, QString *usedText, int *used) { @@ -1267,9 +1270,12 @@ static int findTextEntry(const QString &text, const QVector &entries, Q int i = 0; while (i < limit && text.at(i) == name.at(i).toLower()) ++i; - if (i > bestCount) { + // Full match beats an equal prefix match: + if (i > bestCount || (i == bestCount && i == name.size())) { bestCount = i; bestMatch = n; + if (i == name.size() && i == text.size()) + break; // Exact match, name == text, wins. } } if (usedText && bestMatch != -1) -- cgit v1.2.3 From 5cc0de2e084cb887a75b076b82cf470ecdcd4dd3 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 26 May 2016 08:30:26 +0200 Subject: QAtomic: pass explicit failure memory order to std::atomic::compare_exchange_strong MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 4.8 seems to get the failure memory order wrong when using the overload that only accepts one memory order and produces errors such as: bits/atomic_base.h:577:70: error: failure memory model cannot be stronger than success memory model for '__atomic_compare_exchange' return __atomic_compare_exchange_n(&_M_i, &__i1, __i2, 0, __m1, __m2); ^ (as seen on Android). Fix by explicitly passing the failure orders corresponding to the success orders, as specified by the standard: relaxed → relaxed release → relaxed acquire → acquire acq_rel → acquire (cf. http://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange). Task-number: QTBUG-59399 Change-Id: If046e735888cf331d2d6506d8d5ca9aa7402f9ad Reviewed-by: David Faure Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/arch/qatomic_cxx11.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/arch/qatomic_cxx11.h b/src/corelib/arch/qatomic_cxx11.h index 63b23b71ab..484ec73e7f 100644 --- a/src/corelib/arch/qatomic_cxx11.h +++ b/src/corelib/arch/qatomic_cxx11.h @@ -278,7 +278,7 @@ template struct QAtomicOps template static bool testAndSetRelaxed(std::atomic &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { - bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed, std::memory_order_relaxed); if (currentValue) *currentValue = expectedValue; return tmp; @@ -287,7 +287,7 @@ template struct QAtomicOps template static bool testAndSetAcquire(std::atomic &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { - bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire, std::memory_order_acquire); if (currentValue) *currentValue = expectedValue; return tmp; @@ -296,7 +296,7 @@ template struct QAtomicOps template static bool testAndSetRelease(std::atomic &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { - bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release, std::memory_order_relaxed); if (currentValue) *currentValue = expectedValue; return tmp; @@ -305,7 +305,7 @@ template struct QAtomicOps template static bool testAndSetOrdered(std::atomic &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW { - bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel); + bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel, std::memory_order_acquire); if (currentValue) *currentValue = expectedValue; return tmp; -- cgit v1.2.3 From b52b509ae48125ce9ba3cb50560e2e9ff81b485e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Mon, 27 Feb 2017 14:03:15 +0100 Subject: QLockFile: Don't deadlock if the lock file has a mtime in the future Stale Lock files in the future can happen in some situations. For exemple two computers with different clocks access the same file system. It could be that one of the timestamp is totaly off (several years into the future). [ChangeLog][QtCore][QLockFile] Fixed a deadlock occurring if a corrupted lock file's modification time is in the future. Change-Id: I8dac98a0e898c76bcef67f8c195e126c996b6add Reviewed-by: David Faure --- src/corelib/io/qlockfile.cpp | 3 +++ src/corelib/io/qlockfile_unix.cpp | 2 +- src/corelib/io/qlockfile_win.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index cb1ff93ad3..48317d07e0 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -44,6 +44,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -226,6 +227,8 @@ bool QLockFile::tryLock(int timeout) return false; case LockFailedError: if (!d->isLocked && d->isApparentlyStale()) { + if (Q_UNLIKELY(QFileInfo(d->fileName).lastModified() > QDateTime::currentDateTime())) + qInfo("QLockFile: Lock file '%ls' has a modification time in the future", qUtf16Printable(d->fileName)); // Stale lock from another thread/process // Ensure two processes don't remove it at the same time QLockFile rmlock(d->fileName + QLatin1String(".rmlock")); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 3a80014c00..5a02741727 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -247,7 +247,7 @@ bool QLockFilePrivate::isApparentlyStale() const } } const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); - return staleLockTime > 0 && age > staleLockTime; + return staleLockTime > 0 && qAbs(age) > staleLockTime; } QString QLockFilePrivate::processNameByPid(qint64 pid) diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index baaff8da17..4b43181686 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -160,7 +160,7 @@ bool QLockFilePrivate::isApparentlyStale() const Q_UNUSED(appname); #endif // Q_OS_WINRT const qint64 age = QFileInfo(fileName).lastModified().msecsTo(QDateTime::currentDateTime()); - return staleLockTime > 0 && age > staleLockTime; + return staleLockTime > 0 && qAbs(age) > staleLockTime; } QString QLockFilePrivate::processNameByPid(qint64 pid) -- cgit v1.2.3 From c0da37a806dc0457636d787331e9f50778ee8b3e Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Thu, 9 Mar 2017 10:47:04 -0800 Subject: Fix QStandardPaths values on Apple Platforms containing URL encoding This corrects an issue where the file system paths returned for some QStandardPaths values on Apple Platforms would be URL encoded, for example having %20 instead of an actual space character. Task-number: QTBUG-59389 Change-Id: I771a44eb20b756842c324ac6fc9bdc475ce84826 Reviewed-by: David Faure Reviewed-by: Timur Pocheptsov Reviewed-by: Gabriel de Dietrich --- src/corelib/io/qstandardpaths_mac.mm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qstandardpaths_mac.mm b/src/corelib/io/qstandardpaths_mac.mm index a293d4862f..e25339a7d1 100644 --- a/src/corelib/io/qstandardpaths_mac.mm +++ b/src/corelib/io/qstandardpaths_mac.mm @@ -204,13 +204,14 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) CFBundleRef mainBundle = CFBundleGetMainBundle(); if (mainBundle) { CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle); - CFStringRef cfBundlePath = CFURLCopyPath(bundleUrl); + CFStringRef cfBundlePath = CFURLCopyFileSystemPath(bundleUrl, kCFURLPOSIXPathStyle); QString bundlePath = QString::fromCFString(cfBundlePath); CFRelease(cfBundlePath); CFRelease(bundleUrl); CFURLRef resourcesUrl = CFBundleCopyResourcesDirectoryURL(mainBundle); - CFStringRef cfResourcesPath = CFURLCopyPath(resourcesUrl); + CFStringRef cfResourcesPath = CFURLCopyFileSystemPath(resourcesUrl, + kCFURLPOSIXPathStyle); QString resourcesPath = QString::fromCFString(cfResourcesPath); CFRelease(cfResourcesPath); CFRelease(resourcesUrl); -- cgit v1.2.3 From e364384d9f91e57ad6116d549f3748d165b77ea2 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 14 Mar 2017 11:01:37 +0100 Subject: QChar: fix docs of (uchar) ctor The constructor is not only disabled under QT_NO_CAST_FROM_ASCII, but also under QT_RESTRICTED_CAST_FROM_ASCII. Change-Id: I7bbaf2891913d5256dff7f80c49075ea3326155a Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/corelib/tools/qchar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 287861eee8..5f918aab0f 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -624,9 +624,9 @@ QT_BEGIN_NAMESPACE Constructs a QChar corresponding to ASCII/Latin-1 character \a ch. \note This constructor is not available when \c QT_NO_CAST_FROM_ASCII - is defined. + or QT_RESTRICTED_CAST_FROM_ASCII is defined. - \sa QT_NO_CAST_FROM_ASCII + \sa QT_NO_CAST_FROM_ASCII, QT_RESTRICTED_CAST_FROM_ASCII */ /*! -- cgit v1.2.3 From cdaea1696416bb2c6e1c12519c5d9d6b8bec1969 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 15 Mar 2017 18:58:27 -0700 Subject: Protect better against timer ID replacement Timer IDs have been reused since Qt 4.5 or thereabouts, so just checking if the timer ID is in the timer dictionary is an incorrect check: our timer may have been deleted and replaced by another with the same ID. Instead of deleting the WinTimerInfo object, let's just mark it as unregistered by setting timerId to -1 and cooperate in deleting at the appropriate places. Since unregisterTimer skips deleting if inTimerEvent is true, the appropriate places are everywhere that set inTimerEvent to true. Change-Id: I057e93314e41372ae7a5ff93c467767c8a6d92ea Reviewed-by: Friedemann Kleint Reviewed-by: Oliver Wolff Reviewed-by: Joerg Bornemann --- src/corelib/kernel/qeventdispatcher_win.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 88dbe8e4f7..fd9d41647d 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -406,7 +406,9 @@ void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t) } else if (internalHwnd) { KillTimer(internalHwnd, t->timerId); } - delete t; + t->timerId = -1; + if (!t->inTimerEvent) + delete t; } void QEventDispatcherWin32Private::sendTimerEvent(int timerId) @@ -423,8 +425,9 @@ void QEventDispatcherWin32Private::sendTimerEvent(int timerId) QCoreApplication::sendEvent(t->obj, &e); // timer could have been removed - t = timerDict.value(timerId); - if (t) { + if (t->timerId == -1) { + delete t; + } else { t->inTimerEvent = false; } } @@ -1012,8 +1015,10 @@ bool QEventDispatcherWin32::event(QEvent *e) QTimerEvent te(zte->timerId()); QCoreApplication::sendEvent(t->obj, &te); - t = d->timerDict.value(zte->timerId()); - if (t) { + // timer could have been removed + if (t->timerId == -1) { + delete t; + } else { if (t->interval == 0 && t->inTimerEvent) { // post the next zero timer event as long as the timer was not restarted QCoreApplication::postEvent(this, new QZeroTimerEvent(zte->timerId())); -- cgit v1.2.3 From 4ee74257940e2ed21b653b986ad02a746e8438a6 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Mar 2017 21:36:17 -0700 Subject: Work around Linux libc overflow in mmap64 The mmap64 functions in all Linux libc fail to properly check that the value fits in the system call parameter. I guess the developers just said "16 PB are enough for everyone"... Change-Id: Ic39b2c4fd9c84522a8fafffd14ac91567ce09c09 Reviewed-by: Sami Nurmenniemi Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/io/qfsfileengine_unix.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index bf2f47d399..f8e31ed92b 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -688,6 +688,19 @@ QDateTime QFSFileEngine::fileTime(FileTime time) const uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFlags flags) { +#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, + // regardless of the actual page size). Unfortunately, the mmap64() + // function is known to be broken in all Linux libcs (glibc, uclibc, musl + // 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::max(); +#endif + Q_Q(QFSFileEngine); Q_UNUSED(flags); if (openMode == QIODevice::NotOpen) { @@ -695,7 +708,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla return 0; } - if (offset < 0 || offset != qint64(QT_OFF_T(offset)) + if (offset < 0 || offset > MaxFileOffset || size < 0 || quint64(size) > quint64(size_t(-1))) { q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL))); return 0; -- cgit v1.2.3 From 5c724a6087b0a647e8241d35f0d44bce08e35281 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 17 Mar 2017 11:07:30 +0100 Subject: QChar: fix ambiguous comparisons with 0, '\0', ... for good Commit e0ea0f6178c9dbee2a8c888fde84ad1cd9670c6b optimized QChar <-> QString(Ref) comparisons by adding more overloads to avoid creating QStrings from QChars just to compare them. But these new overloads made existing comparisons to QChar ambiguous. This was known at the time for QChar/int comparisons. It has since turned out that also comparing to '\0' is ambiguous, ie. not comparing to int or char per se is ambiguous, but comparing to nullptr constants is, because QString(const char*) is just as good a candidate as QChar(char)/QChar(int). Since we allow QString/QChar comparisons, it seems logical to solve the problem by adding QChar<->nullptr overloads. [ChangeLog][QtCore][QChar] Disambiguated comparisons with nullptr constants such as '\0', which 5.8.0 broke. As a consequence, QChar<->int comparisons are no longer deprecated, as this was a failed attempt at fixing the ambiguity. Change-Id: I680dd509c2286e96894e13078899dbe3b2dd83bc Reviewed-by: Thiago Macieira --- src/corelib/tools/qchar.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h index a83e5e6f98..81ef67d116 100644 --- a/src/corelib/tools/qchar.h +++ b/src/corelib/tools/qchar.h @@ -578,17 +578,21 @@ Q_DECL_CONSTEXPR inline bool operator>=(QChar c1, QChar c2) Q_DECL_NOTHROW { ret Q_DECL_CONSTEXPR inline bool operator> (QChar c1, QChar c2) Q_DECL_NOTHROW { return operator< (c2, c1); } Q_DECL_CONSTEXPR inline bool operator<=(QChar c1, QChar c2) Q_DECL_NOTHROW { return !operator< (c2, c1); } -// disambiguate QChar == int (but only that, so constrain template to exactly 'int'): -template -Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead") -Q_DECL_CONSTEXPR inline -typename std::enable_if::type, int>::value, bool>::type -operator==(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs == QChar(rhs); } -template -Q_DECL_DEPRECATED_X("don't compare ints to QChars, compare them to QChar::unicode() instead") -Q_DECL_CONSTEXPR inline -typename std::enable_if::type, int>::value, bool>::type -operator!=(QChar lhs, T rhs) Q_DECL_NOEXCEPT { return lhs != QChar(rhs); } + +Q_DECL_CONSTEXPR inline bool operator==(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return lhs.isNull(); } +Q_DECL_CONSTEXPR inline bool operator< (QChar, std::nullptr_t) Q_DECL_NOTHROW { return false; } +Q_DECL_CONSTEXPR inline bool operator==(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return rhs.isNull(); } +Q_DECL_CONSTEXPR inline bool operator< (std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !rhs.isNull(); } + +Q_DECL_CONSTEXPR inline bool operator!=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator==(lhs, nullptr); } +Q_DECL_CONSTEXPR inline bool operator>=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator< (lhs, nullptr); } +Q_DECL_CONSTEXPR inline bool operator> (QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return operator< (nullptr, lhs); } +Q_DECL_CONSTEXPR inline bool operator<=(QChar lhs, std::nullptr_t) Q_DECL_NOTHROW { return !operator< (nullptr, lhs); } + +Q_DECL_CONSTEXPR inline bool operator!=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator==(nullptr, rhs); } +Q_DECL_CONSTEXPR inline bool operator>=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator< (nullptr, rhs); } +Q_DECL_CONSTEXPR inline bool operator> (std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return operator< (rhs, nullptr); } +Q_DECL_CONSTEXPR inline bool operator<=(std::nullptr_t, QChar rhs) Q_DECL_NOTHROW { return !operator< (rhs, nullptr); } #ifndef QT_NO_DATASTREAM Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, QChar); -- cgit v1.2.3 From 4a97e3b98a40e6d35a4e63e171319ed02961a0cc Mon Sep 17 00:00:00 2001 From: Anton Kudryavtsev Date: Fri, 17 Mar 2017 00:07:57 +0300 Subject: QMap, QHash: make key_iterator satisfy the DefaultConstructible concept Change-Id: Ifc3f481ddb902b26c217516412c93a4a39a32b1c Reviewed-by: Marc Mutz --- src/corelib/tools/qhash.h | 1 + src/corelib/tools/qmap.h | 1 + 2 files changed, 2 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 66b5e75a1a..c59f789cb2 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -432,6 +432,7 @@ public: typedef const Key *pointer; typedef const Key &reference; + key_iterator() = default; explicit key_iterator(const_iterator o) : i(o) { } const Key &operator*() const { return i.key(); } diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index e6da2820f8..3ee6ab8c58 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -531,6 +531,7 @@ public: typedef const Key *pointer; typedef const Key &reference; + key_iterator() = default; explicit key_iterator(const_iterator o) : i(o) { } const Key &operator*() const { return i.key(); } -- cgit v1.2.3 From 035e0eafa607217f8110a492a9be7d0718e34907 Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 15 Mar 2017 12:03:18 +0100 Subject: QUrl::fromUserInput: fix handling of files with a ':' in the name QUrl::isRelative(str) would be false for such files, so first check for file existence before doing any URL parsing. Change-Id: I51b6229251ad94877ac408b2f8018456d3e10a36 Reviewed-by: Shawn Rutledge Reviewed-by: Thiago Macieira --- src/corelib/io/qurl.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 520ad2e5d3..3df7070557 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -4170,12 +4170,15 @@ QUrl QUrl::fromUserInput(const QString &userInput, const QString &workingDirecto return url; } + const QFileInfo fileInfo(QDir(workingDirectory), userInput); + if (fileInfo.exists()) { + return QUrl::fromLocalFile(fileInfo.absoluteFilePath()); + } + QUrl url = QUrl(userInput, QUrl::TolerantMode); // Check both QUrl::isRelative (to detect full URLs) and QDir::isAbsolutePath (since on Windows drive letters can be interpreted as schemes) - if (url.isRelative() && !QDir::isAbsolutePath(userInput)) { - QFileInfo fileInfo(QDir(workingDirectory), userInput); - if ((options & AssumeLocalFile) || fileInfo.exists()) - return QUrl::fromLocalFile(fileInfo.absoluteFilePath()); + if ((options & AssumeLocalFile) && url.isRelative() && !QDir::isAbsolutePath(userInput)) { + return QUrl::fromLocalFile(fileInfo.absoluteFilePath()); } return fromUserInput(trimmedString); -- cgit v1.2.3 From 202d6ad73059d4dd1199fd1e8785d29018749f32 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 14 Mar 2017 11:31:52 -0700 Subject: QHash: unexport the hash seed variable The only allowed way to access the variable is now via the public qGlobalQHashSeed and qSetGlobalQHashSeed functions. The variable was private API, so we're allowed to remove it. Task-number: QTBUG-47566 Change-Id: I4a7dc1fe14154695b968fffd14abd331e5810482 Reviewed-by: Jake Petroules Reviewed-by: David Faure --- src/corelib/tools/qhash.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 9270539f4f..334bd52f1e 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -325,7 +325,7 @@ static uint qt_create_qhash_seed() /* The QHash seed itself. */ -Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed = Q_BASIC_ATOMIC_INITIALIZER(-1); +static QBasicAtomicInt qt_qhash_seed = Q_BASIC_ATOMIC_INITIALIZER(-1); /*! \internal -- cgit v1.2.3 From 99fc96fd373b6ffdf9a66e4a346885de20645533 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 9 Mar 2017 13:44:00 +0100 Subject: QMetaType & QVariant: "load" and "save" std::nullptr_t We don't load and save pointers usually because the pointer value cannot be guaranteed to remain across program invocations. However, nullptr is an exception: a null pointer is always a null pointer. We don't actually have to read or write anything: there's only one value possible for a std::nullptr_t and it is nullptr. [ChangeLog][Important Behavior Changes] A QVariant containing a std::nullptr_t is now streamable to/from QDataStream. Task-number: QTBUG-59391 Change-Id: Iae839f6a131a4f0784bffffd14aa374f6475d283 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Lars Knoll --- src/corelib/kernel/qmetatype.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 232a134718..718c42ba55 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -1255,7 +1255,6 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data) case QMetaType::UnknownType: case QMetaType::Void: case QMetaType::VoidStar: - case QMetaType::Nullptr: case QMetaType::QObjectStar: case QMetaType::QModelIndex: case QMetaType::QPersistentModelIndex: @@ -1264,6 +1263,8 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data) case QMetaType::QJsonArray: case QMetaType::QJsonDocument: return false; + case QMetaType::Nullptr: + return true; case QMetaType::Long: stream << qlonglong(*static_cast(data)); break; @@ -1477,7 +1478,6 @@ bool QMetaType::load(QDataStream &stream, int type, void *data) case QMetaType::UnknownType: case QMetaType::Void: case QMetaType::VoidStar: - case QMetaType::Nullptr: case QMetaType::QObjectStar: case QMetaType::QModelIndex: case QMetaType::QPersistentModelIndex: @@ -1486,6 +1486,8 @@ bool QMetaType::load(QDataStream &stream, int type, void *data) case QMetaType::QJsonArray: case QMetaType::QJsonDocument: return false; + case QMetaType::Nullptr: + return true; case QMetaType::Long: { qlonglong l; stream >> l; -- cgit v1.2.3 From 9021a748afc9a380feb80dc4d1a824c4d77f2aa1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 17 Mar 2017 14:03:08 -0700 Subject: QStorageInfo: Fix warning about unused variable Happens on non-Linux, non-macOS Unix systems (got it on FreeBSD). Change-Id: Ie67d35dff21147e99ad9fffd14acc7308b5ff17e Reviewed-by: Jake Petroules Reviewed-by: Oswald Buddenhagen --- src/corelib/io/qstorageinfo_unix.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index fcc7b8ca50..b9c9883609 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -503,6 +503,8 @@ static QByteArray extractSubvolume(const QStorageIterator &it) // if we didn't find the subvolume name, return the subvolume ID return id; } +#else + Q_UNUSED(it); #endif return QByteArray(); } -- cgit v1.2.3 From e5c0371d18e285d7849cbd0569970e209bd01b49 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Fri, 3 Mar 2017 14:40:40 +0100 Subject: Fix propagation of locale from widget to its children Fix the condition in QWidgetPrivate::resolveLocale() to decide whether to propagate locale: make it match setLocale_helper()'s condition when deciding whether to propagate to descendants. This lead to a QDateTimeEdit's calendar popup not getting told what locale to use correctly, unless we setLocale() on it overtly, which then blocked propagation of locale changes to it unless QDateTimeEdit manually propagated the changes. Fix the documentation of WA_WindowPropagation to mention locale as also being propagated (which it was in several places, only neglecting this one in resolveLocale). [ChangeLog][QWidget][Qt::WA_WindowPropagation] Propagate locale consistently, along with font and palette, within the widget hierarchy. Previously, locale was propagated on ancestral setLocale(), but not on creation of the descendant. Task-number: QTBUG-59106 Change-Id: I92270f7789c8eda66a458274a658c84c7b0df754 Reviewed-by: David Faure --- src/corelib/global/qnamespace.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 71cd9444d6..59fa0b519c 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1151,8 +1151,8 @@ and Windows) the window will take a modified appearance. This flag is set or cleared by QWidget::setWindowModified(). - \value WA_WindowPropagation Makes a toplevel window inherit font and - palette from its parent. + \value WA_WindowPropagation Makes a toplevel window inherit font, palette + and locale from its parent. \value WA_MacAlwaysShowToolWindow On \macos, show the tool window even when the application is not active. By default, all tool windows are -- cgit v1.2.3 From e19fda916aa92f8890199dc4b9d56884c55d0cd8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 23 Mar 2017 15:18:00 -0700 Subject: Fix some warnings found by QNX's compiler -Werror is now disabled for that compiler, but it doesn't hurt to fix. io/qstandardpaths_unix.cpp:149:32: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare] qtestcase.cpp:2330:31: error: narrowing conversion of '(ms / 1000)' from 'int' to '_Timet {aka unsigned int}' inside { } [-Werror=narrowing] Change-Id: Id92f4a61915b49ddaee6fffd14aea2c1e686e8f2 Reviewed-by: Samuli Piippo --- src/corelib/io/qstandardpaths_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index 7974dc8cca..f0ff46fe7f 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -117,7 +117,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) } case RuntimeLocation: { - const uid_t myUid = geteuid(); + const uint myUid = uint(geteuid()); // http://standards.freedesktop.org/basedir-spec/latest/ QFileInfo fileInfo; QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR")); -- cgit v1.2.3 From 5ca7d56aca5d7cae3f6eefad181839f9b3a2ece6 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sat, 25 Mar 2017 08:09:03 +0100 Subject: QVarLengthArray: fix compilation with GCC 7 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes a warning-turned-Werror in qdistancefield.cpp: In member function ‘void QVarLengthArray::realloc(int, int) [with T = bool; int Prealloc = 256]’, inlined from ‘void makeDistanceField(QDistanceFieldData*, const QPainterPath&, int, int)’ at ../../include/QtCore/../../../../qt5/qtbase/src/corelib/tools/qvarlengtharray.h:275:10: ../../include/QtCore/../../../../qt5/qtbase/src/corelib/tools/qvarlengtharray.h:390:19: error: ‘void* memcpy(void*, const void*, size_t)’: specified size between 18446744071562067968 and 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Werror=stringop-overflow=] memcpy(ptr, oldPtr, copySize * sizeof(T)); ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Apparently GCC cannot rule out that copySize may be negative in the call to memcpy. Put GCC on the right track by adding a Q_ASSUME. Change-Id: I63e3801e52ebe2a7f77e3a97ef03ec3869319c8c Reviewed-by: Thiago Macieira Reviewed-by: Konstantin Ritt Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qvarlengtharray.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/corelib') diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index 2d3c25a5dd..8b9df7c12b 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -350,6 +350,7 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray::realloc(int asize, int a int osize = s; const int copySize = qMin(asize, osize); + Q_ASSUME(copySize >= 0); if (aalloc != a) { if (aalloc > Prealloc) { T* newPtr = reinterpret_cast(malloc(aalloc * sizeof(T))); -- cgit v1.2.3 From d8e2db017392cff7c57cab0d271e5677109f3bd7 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 22 Mar 2017 14:27:25 +0100 Subject: QDir: replace QLVA with QVLA ... as used in qstring.cpp, too. QChar is only marked as movable, not primitive, as it should have been and ushort is, and there's some hope that the template instantiations can be shared across TUs. Saves a rather disappointing 148B in text size on optimized GCC 7 Linux AMD64 builds. Change-Id: Ic9558a4d83611a6461cd5540c9090cbd4c4f2f4e Reviewed-by: Thiago Macieira --- src/corelib/io/qdir.cpp | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index bfb91c131f..6d144cb65d 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -2105,11 +2105,11 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all return name; int i = len - 1; - QVarLengthArray outVector(len); + QVarLengthArray outVector(len); int used = len; - QChar *out = outVector.data(); - const QChar *p = name.unicode(); - const QChar *prefix = p; + ushort *out = outVector.data(); + const ushort *p = name.utf16(); + const ushort *prefix = p; int up = 0; const int prefixLength = rootLength(name, allowUncPaths); @@ -2117,39 +2117,39 @@ 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].unicode() == '/') { - out[--used].unicode() = '/'; + if (i > 0 && p[i] == '/') { + out[--used] = '/'; --i; } while (i >= 0) { // remove trailing slashes - if (p[i].unicode() == '/') { + if (p[i] == '/') { --i; continue; } // remove current directory - if (p[i].unicode() == '.' && (i == 0 || p[i-1].unicode() == '/')) { + if (p[i] == '.' && (i == 0 || p[i-1] == '/')) { --i; continue; } // detect up dir - if (i >= 1 && p[i].unicode() == '.' && p[i-1].unicode() == '.' - && (i == 1 || (i >= 2 && p[i-2].unicode() == '/'))) { + if (i >= 1 && p[i] == '.' && p[i-1] == '.' + && (i == 1 || (i >= 2 && p[i-2] == '/'))) { ++up; i -= 2; continue; } // prepend a slash before copying when not empty - if (!up && used != len && out[used].unicode() != '/') - out[--used] = QLatin1Char('/'); + if (!up && used != len && out[used] != '/') + out[--used] = '/'; // skip or copy while (i >= 0) { - if (p[i].unicode() == '/') { // do not copy slashes + if (p[i] == '/') { // do not copy slashes --i; break; } @@ -2171,17 +2171,17 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all // add remaining '..' while (up) { - if (used != len && out[used].unicode() != '/') // is not empty and there isn't already a '/' - out[--used] = QLatin1Char('/'); - out[--used] = QLatin1Char('.'); - out[--used] = QLatin1Char('.'); + if (used != len && out[used] != '/') // is not empty and there isn't already a '/' + out[--used] = '/'; + out[--used] = '.'; + out[--used] = '.'; --up; } bool isEmpty = used == len; if (prefixLength) { - if (!isEmpty && out[used].unicode() == '/') { + if (!isEmpty && out[used] == '/') { // Eventhough there is a prefix the out string is a slash. This happens, if the input // string only consists of a prefix followed by one or more slashes. Just skip the slash. ++used; @@ -2192,18 +2192,19 @@ Q_AUTOTEST_EXPORT QString qt_normalizePathSegments(const QString &name, bool all if (isEmpty) { // After resolving the input path, the resulting string is empty (e.g. "foo/.."). Return // a dot in that case. - out[--used] = QLatin1Char('.'); - } else if (out[used].unicode() == '/') { + out[--used] = '.'; + } else if (out[used] == '/') { // After parsing the input string, out only contains a slash. That happens whenever all // parts are resolved and there is a trailing slash ("./" or "foo/../" for example). // Prepend a dot to have the correct return value. - out[--used] = QLatin1Char('.'); + out[--used] = '.'; } } // If path was not modified return the original value - QString ret = (used == 0 ? name : QString(out + used, len - used)); - return ret; + if (used == 0) + return name; + return QString::fromUtf16(out + used, len - used); } static QString qt_cleanPath(const QString &path, bool *ok) -- cgit v1.2.3 From 38550c562d918e783bb609622bc8fb46de1bfec4 Mon Sep 17 00:00:00 2001 From: Marius Kittler Date: Mon, 27 Feb 2017 22:16:41 +0100 Subject: json encoder: Harmonize number serialization with ES6 Ensures that numbers representable as 64-bit integer are not printed using exponent notation. Some JSON implementations such as the one of the Go standard library expect this in the default conversion to int. Change-Id: Ic3ac718b7fd36462b4fcabbfb100a528a87798c8 Reviewed-by: Thiago Macieira --- src/corelib/json/qjsonwriter.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp index b1544c749d..12ce20ef09 100644 --- a/src/corelib/json/qjsonwriter.cpp +++ b/src/corelib/json/qjsonwriter.cpp @@ -38,6 +38,7 @@ ** ****************************************************************************/ +#include #include #include "qjsonwriter_p.h" #include "qjson_p.h" @@ -129,10 +130,12 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value & break; case QJsonValue::Double: { const double d = v.toDouble(b); - if (qIsFinite(d)) // +2 to format to ensure the expected precision - json += QByteArray::number(d, 'g', QLocale::FloatingPointShortest); - else + if (qIsFinite(d)) { // +2 to format to ensure the expected precision + const double abs = std::abs(d); + json += QByteArray::number(d, abs == static_cast(abs) ? 'f' : 'g', QLocale::FloatingPointShortest); + } else { json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4) + } break; } case QJsonValue::String: -- cgit v1.2.3 From 1dd54b5647d33416c39fb41fdab560c815356951 Mon Sep 17 00:00:00 2001 From: Kimmo Ollila Date: Tue, 21 Mar 2017 00:06:23 +0200 Subject: Increase the maximum recursive template depth on INTEGRITY Set the limit to 128 instead of the default 64 by adding QMAKE_CXXFLAGS += --pending_instantiations=128. This is needed by QMetaType::typeName array implementation. Change-Id: I3fd13967f862f492210572cfe7ee9ffc5e7c9745 Reviewed-by: Lars Knoll Reviewed-by: Thiago Macieira --- src/corelib/kernel/kernel.pri | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 461fbd7840..0e6ff17b8f 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -175,6 +175,9 @@ unix|integrity { SOURCES += kernel/qsharedmemory_android.cpp \ kernel/qsystemsemaphore_android.cpp } + + # This is needed by QMetaType::typeName array implementation + integrity: QMAKE_CXXFLAGS += --pending_instantiations=128 } vxworks { -- cgit v1.2.3 From 1e7795ef604fe22895b8ec5c2278fea4217f2c07 Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Tue, 21 Mar 2017 12:26:36 +0100 Subject: Add documentation for TabletTrackingChange enum value Amends 6aaf8532222759226a9b406bfe6c57787236cbf1 Change-Id: I2c264db235ea552ce6b4eb003d7daeeb2cecde6f Reviewed-by: Friedemann Kleint Reviewed-by: Venugopal Shivashankar --- src/corelib/kernel/qcoreevent.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 64e73d23c5..4efc38ac89 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -216,6 +216,7 @@ QT_BEGIN_NAMESPACE \omitvalue OkRequest \value TabletEnterProximity Wacom tablet enter proximity event (QTabletEvent), sent to QApplication. \value TabletLeaveProximity Wacom tablet leave proximity event (QTabletEvent), sent to QApplication. + \value TabletTrackingChange The Wacom tablet tracking state has changed (since Qt 5.9). \omitvalue ThemeChange \value ThreadChange The object is moved to another thread. This is the last event sent to this object in the previous thread. See QObject::moveToThread(). \value Timer Regular timer events (QTimerEvent). -- cgit v1.2.3