From f2df5c64bde5a3837048347b18c246e674de5caa Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 12 Jun 2017 15:31:53 +0200 Subject: QFileSystemEntry: Export static helper function checking for the root path This provides a helper function which does the check on the string. QFileInfo::isRoot() in addition checks for the existence of the directory, which can cause hangs with network drives. Use the new function in appropriate places in QtWidgets. Task-number: QTBUG-6039 Change-Id: I54d0d860713e82b28fa4069a5345b042337f9c52 Reviewed-by: Joerg Bornemann --- src/corelib/io/qfilesystementry.cpp | 30 ++++++++++++++++++++---------- src/corelib/io/qfilesystementry_p.h | 3 +++ 2 files changed, 23 insertions(+), 10 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qfilesystementry.cpp b/src/corelib/io/qfilesystementry.cpp index de4c852068..cbff17d0f1 100644 --- a/src/corelib/io/qfilesystementry.cpp +++ b/src/corelib/io/qfilesystementry.cpp @@ -297,23 +297,27 @@ bool QFileSystemEntry::isAbsolute() const bool QFileSystemEntry::isDriveRoot() const { resolveFilePath(); + return QFileSystemEntry::isDriveRootPath(m_filePath); +} + +bool QFileSystemEntry::isDriveRootPath(const QString &path) +{ #ifndef Q_OS_WINRT - return (m_filePath.length() == 3 - && m_filePath.at(0).isLetter() && m_filePath.at(1) == QLatin1Char(':') - && m_filePath.at(2) == QLatin1Char('/')); + return (path.length() == 3 + && path.at(0).isLetter() && path.at(1) == QLatin1Char(':') + && path.at(2) == QLatin1Char('/')); #else // !Q_OS_WINRT - return m_filePath == QDir::rootPath(); + return path == QDir::rootPath(); #endif // !Q_OS_WINRT } -#endif +#endif // Q_OS_WIN -bool QFileSystemEntry::isRoot() const +bool QFileSystemEntry::isRootPath(const QString &path) { - resolveFilePath(); - if (m_filePath == QLatin1String("/") + if (path == QLatin1String("/") #if defined(Q_OS_WIN) - || isDriveRoot() - || isUncRoot(m_filePath) + || isDriveRootPath(path) + || isUncRoot(path) #endif ) return true; @@ -321,6 +325,12 @@ bool QFileSystemEntry::isRoot() const return false; } +bool QFileSystemEntry::isRoot() const +{ + resolveFilePath(); + return isRootPath(m_filePath); +} + bool QFileSystemEntry::isEmpty() const { return m_filePath.isEmpty() && m_nativeFilePath.isEmpty(); diff --git a/src/corelib/io/qfilesystementry_p.h b/src/corelib/io/qfilesystementry_p.h index 300a375377..700696d09e 100644 --- a/src/corelib/io/qfilesystementry_p.h +++ b/src/corelib/io/qfilesystementry_p.h @@ -94,6 +94,7 @@ public: #if defined(Q_OS_WIN) bool isDriveRoot() const; + static bool isDriveRootPath(const QString &path); #endif bool isRoot() const; @@ -103,6 +104,8 @@ public: *this = QFileSystemEntry(); } + Q_CORE_EXPORT static bool isRootPath(const QString &path); + private: // creates the QString version out of the bytearray version void resolveFilePath() const; -- cgit v1.2.3 From df06926b8a25316db5c21a82e68beb097999e7b2 Mon Sep 17 00:00:00 2001 From: David Faure Date: Sat, 25 Feb 2017 11:56:12 +0100 Subject: QMimeDatabase::mimeTypeForUrl: skip content check for remote URLs The code was trying to open a local file with the same path as the remote URL, which is unnecessary and wrong in the unlikely case where such a file would exist. Spotted by Christoph Feck when reading the code. Change-Id: I1d77e5781cf606b025d2877f48a9914dd1e36b1d Reviewed-by: Giuseppe D'Angelo --- src/corelib/mimetypes/qmimedatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp index fda9f01643..687f0b3e03 100644 --- a/src/corelib/mimetypes/qmimedatabase.cpp +++ b/src/corelib/mimetypes/qmimedatabase.cpp @@ -526,7 +526,7 @@ QMimeType QMimeDatabase::mimeTypeForUrl(const QUrl &url) const if (scheme.startsWith(QLatin1String("http")) || scheme == QLatin1String("mailto")) return mimeTypeForName(d->defaultMimeType()); - return mimeTypeForFile(url.path()); + return mimeTypeForFile(url.path(), MatchExtension); } /*! -- cgit v1.2.3 From 8616b2112c0f24f71892488cefb146ae3505da9e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Jun 2017 22:32:34 -0700 Subject: Fix parsing of 0E+1 and 0E-1 (capital 'E') Since the result is an actual zero, this section of code looking for underflows kicks in. But we forgot to take the capital letter into account when parsing the number. Task-number: QTBUG-61350 Change-Id: Ia53158e207a94bf49489fffd14c6abbd21f0bac0 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/tools/qlocale_tools.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qlocale_tools.cpp b/src/corelib/tools/qlocale_tools.cpp index 762f4f36dc..3e4f37501e 100644 --- a/src/corelib/tools/qlocale_tools.cpp +++ b/src/corelib/tools/qlocale_tools.cpp @@ -370,7 +370,7 @@ double asciiToDouble(const char *num, int numLen, bool &ok, int &processed, // if a digit before any 'e' is not 0, then a non-zero number was intended. ok = false; return 0.0; - } else if (num[i] == 'e') { + } else if (num[i] == 'e' || num[i] == 'E') { break; } } -- cgit v1.2.3 From fb046c932f0d1c54a2baf3633de26926c939082b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Fri, 9 Jun 2017 14:46:01 -0700 Subject: Fix build with MSVC 2015 Update 2 if constexpr is enabled This compiler seems to require explicit initialization of all member variables in a constexpr constructor, even if they have an implicit default constructor of their own. We probably fixed the rest of Qt a couple of years ago, but not these two places because they were arrays and those require the C++11 syntax for uniform initialization. All compilers that support constexpr do support uniform initialization. MSVC 2015 fixed our issues with it on the same update. Change-Id: Ibc1eb23e3ae093f5c6928ded3a041be35eb9baae Reviewed-by: Marc Mutz Reviewed-by: Thiago Macieira --- src/corelib/tools/qfreelist_p.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/tools/qfreelist_p.h b/src/corelib/tools/qfreelist_p.h index a8d1132d06..2f98cf5cc1 100644 --- a/src/corelib/tools/qfreelist_p.h +++ b/src/corelib/tools/qfreelist_p.h @@ -207,7 +207,11 @@ public: template Q_DECL_CONSTEXPR inline QFreeList::QFreeList() - : _next(ConstantsType::InitialNextValue) + : +#if defined(Q_COMPILER_CONSTEXPR) + _v{}, // uniform initialization required +#endif + _next(ConstantsType::InitialNextValue) { } template -- cgit v1.2.3 From 2b991efc476c7d50ee606dd4ddb7d15777bbfe8e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 14 Jun 2017 14:46:33 -0700 Subject: Use QMessageLogger context properly in qglobal.cpp redirects qt_assert and qt_check_pointer get the function name and line number from the caller (the functions are called from the Q_ASSERT and Q_CHECK_PTR macros, respectively), so we don't need to capture the context from those two functions. Instead, pass the context to QMessageLogger for proper logging. I've left the file name and line number in the assertions, for users who did not add them to their message log pattern, but I've removed from the almost never used qt_check_pointer function. Note: how useful is it that we allocate memory in response to failing to allocate memory? Change-Id: Ia53158e207a94bf49489fffd14c81b359c5b6537 Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne --- src/corelib/global/qglobal.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 5b57e1ad61..4f0110dca4 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -97,6 +97,12 @@ #include "archdetect.cpp" +#ifdef qFatal +// the qFatal in this file are just redirections from elsewhere, so +// don't capture any context again +# undef qFatal +#endif + QT_BEGIN_NAMESPACE #if !QT_DEPRECATED_SINCE(5, 0) @@ -3016,7 +3022,7 @@ QString QSysInfo::machineHostName() */ void qt_check_pointer(const char *n, int l) { - qFatal("In file %s, line %d: Out of memory", n, l); + QMessageLogger(n, l, nullptr).fatal("Out of memory"); } /* @@ -3046,7 +3052,7 @@ Q_NORETURN void qTerminate() Q_DECL_NOTHROW */ void qt_assert(const char *assertion, const char *file, int line) Q_DECL_NOTHROW { - qFatal("ASSERT: \"%s\" in file %s, line %d", assertion, file, line); + QMessageLogger(file, line, nullptr).fatal("ASSERT: \"%s\" in file %s, line %d", assertion, file, line); } /* @@ -3054,7 +3060,7 @@ void qt_assert(const char *assertion, const char *file, int line) Q_DECL_NOTHROW */ void qt_assert_x(const char *where, const char *what, const char *file, int line) Q_DECL_NOTHROW { - qFatal("ASSERT failure in %s: \"%s\", file %s, line %d", where, what, file, line); + QMessageLogger(file, line, nullptr).fatal("ASSERT failure in %s: \"%s\", file %s, line %d", where, what, file, line); } -- cgit v1.2.3 From 2f8a08f31b1bfdc18766bae4983d238ee1cf716c Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 14 Jun 2017 15:06:09 -0700 Subject: Make qt_check_pointer more OOM-safe First, it can never return, so we can mark it Q_NORETURN and add an std::termianate at the end. Though if it did, we'd end up in a null- pointer dereference crash in the caller. Second, add Q_DECL_NOTHROW to it. It can't throw, but it terminates execution. This also prevents both puts and fprintf from escaping via pthread asynchronous cancellation on Linux/glibc. Third, don't use QMessageLogger, since that allocates memory and actually uses QString. If we really are in an OOM situation, then QString's failed allocation would recurse back into qt_check_pointer. We'd compound the OOM situation with a stack overflow... Change-Id: Ia53158e207a94bf49489fffd14c81c47971f4e82 Reviewed-by: Friedemann Kleint Reviewed-by: Thiago Macieira --- src/corelib/global/qglobal.cpp | 17 ++++++++++++----- src/corelib/global/qglobal.h | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 4f0110dca4..9b76c72c0d 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -3016,13 +3016,20 @@ QString QSysInfo::machineHostName() If this macro is used outside a function, the behavior is undefined. */ -/* - The Q_CHECK_PTR macro calls this function if an allocation check - fails. +/*! + \internal + The Q_CHECK_PTR macro calls this function if an allocation check + fails. */ -void qt_check_pointer(const char *n, int l) +void qt_check_pointer(const char *n, int l) Q_DECL_NOTHROW { - QMessageLogger(n, l, nullptr).fatal("Out of memory"); + // make separate printing calls so that the first one may flush; + // the second one could want to allocate memory (fputs prints a + // newline and stderr auto-flushes). + fputs("Out of memory", stderr); + fprintf(stderr, " in %s, line %d\n", n, l); + + std::terminate(); } /* diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index f2f28343c6..0c74ed4a3e 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -753,7 +753,7 @@ template <> class QStaticAssertFailure {}; #define Q_STATIC_ASSERT_X(Condition, Message) Q_STATIC_ASSERT(Condition) #endif -Q_CORE_EXPORT void qt_check_pointer(const char *, int); +Q_NORETURN Q_CORE_EXPORT void qt_check_pointer(const char *, int) Q_DECL_NOTHROW; Q_CORE_EXPORT void qBadAlloc(); #ifdef QT_NO_EXCEPTIONS -- cgit v1.2.3