summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/widgets/itemviews/spreadsheet/printview.cpp12
-rw-r--r--examples/widgets/itemviews/spreadsheet/spreadsheet.cpp2
-rw-r--r--examples/widgets/richtext/textedit/textedit.cpp12
-rw-r--r--examples/widgets/tutorials/notepad/notepad.pro2
-rw-r--r--examples/widgets/widgets/imageviewer/imageviewer.cpp9
-rw-r--r--examples/widgets/widgets/imageviewer/imageviewer.h10
-rw-r--r--src/corelib/itemmodels/qsortfilterproxymodel.cpp5
-rw-r--r--src/corelib/kernel/qmetatype.cpp3
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp15
-rw-r--r--src/corelib/plugin/qlibrary.cpp83
-rw-r--r--src/corelib/plugin/qlibrary_p.h26
-rw-r--r--src/corelib/plugin/qlibrary_unix.cpp30
-rw-r--r--src/corelib/plugin/qlibrary_win.cpp30
-rw-r--r--src/corelib/plugin/qpluginloader.cpp8
-rw-r--r--src/corelib/serialization/qcborvalue_p.h3
-rw-r--r--src/gui/kernel/qwindow.cpp10
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp13
-rw-r--r--src/gui/text/qtextmarkdownimporter.cpp7
-rw-r--r--src/gui/text/qtextmarkdownimporter_p.h3
-rw-r--r--src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp21
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h3
-rw-r--r--src/tools/uic/cpp/cppwriteinitialization.cpp19
-rw-r--r--src/xml/dom/qdom.cpp7
-rw-r--r--tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp50
-rw-r--r--tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST3
-rw-r--r--tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp2
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20450.md5
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20580.md1
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/qtextmarkdownimporter.pro2
-rw-r--r--tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp24
-rw-r--r--tests/auto/widgets/kernel/qwidget_window/BLACKLIST4
-rw-r--r--tests/auto/xml/dom/qdom/tst_qdom.cpp24
36 files changed, 300 insertions, 158 deletions
diff --git a/examples/widgets/itemviews/spreadsheet/printview.cpp b/examples/widgets/itemviews/spreadsheet/printview.cpp
index 7db1a6bad9..7700b4ed6a 100644
--- a/examples/widgets/itemviews/spreadsheet/printview.cpp
+++ b/examples/widgets/itemviews/spreadsheet/printview.cpp
@@ -50,8 +50,12 @@
#include "printview.h"
-#ifndef QT_NO_PRINTER
-#include <QPrinter>
+#if defined(QT_PRINTSUPPORT_LIB)
+# include <QtPrintSupport/qtprintsupportglobal.h>
+
+# if QT_CONFIG(printer)
+# include <QPrinter>
+# endif
#endif
PrintView::PrintView()
@@ -62,9 +66,11 @@ PrintView::PrintView()
void PrintView::print(QPrinter *printer)
{
-#ifndef QT_NO_PRINTER
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
resize(printer->width(), printer->height());
render(printer);
+#else
+ Q_UNUSED(printer)
#endif
}
diff --git a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp
index fc7fbb872c..ac8ea7d437 100644
--- a/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp
+++ b/examples/widgets/itemviews/spreadsheet/spreadsheet.cpp
@@ -638,7 +638,7 @@ QString encode_pos(int row, int col)
void SpreadSheet::print()
{
-#if QT_CONFIG(printpreviewdialog)
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printpreviewdialog)
QPrinter printer(QPrinter::ScreenResolution);
QPrintPreviewDialog dlg(&printer);
PrintView view;
diff --git a/examples/widgets/richtext/textedit/textedit.cpp b/examples/widgets/richtext/textedit/textedit.cpp
index 7708b25a24..c9173bcb99 100644
--- a/examples/widgets/richtext/textedit/textedit.cpp
+++ b/examples/widgets/richtext/textedit/textedit.cpp
@@ -197,7 +197,7 @@ void TextEdit::setupFileActions()
a->setPriority(QAction::LowPriority);
menu->addSeparator();
-#ifndef QT_NO_PRINTER
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
const QIcon printIcon = QIcon::fromTheme("document-print", QIcon(rsrcPath + "/fileprint.png"));
a = menu->addAction(printIcon, tr("&Print..."), this, &TextEdit::filePrint);
a->setPriority(QAction::LowPriority);
@@ -559,7 +559,7 @@ void TextEdit::filePrint()
void TextEdit::filePrintPreview()
{
-#if QT_CONFIG(printpreviewdialog)
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printpreviewdialog)
QPrinter printer(QPrinter::HighResolution);
QPrintPreviewDialog preview(&printer, this);
connect(&preview, &QPrintPreviewDialog::paintRequested, this, &TextEdit::printPreview);
@@ -569,17 +569,17 @@ void TextEdit::filePrintPreview()
void TextEdit::printPreview(QPrinter *printer)
{
-#ifdef QT_NO_PRINTER
- Q_UNUSED(printer);
-#else
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
textEdit->print(printer);
+#else
+ Q_UNUSED(printer)
#endif
}
void TextEdit::filePrintPdf()
{
-#ifndef QT_NO_PRINTER
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
//! [0]
QFileDialog fileDialog(this, tr("Export PDF"));
fileDialog.setAcceptMode(QFileDialog::AcceptSave);
diff --git a/examples/widgets/tutorials/notepad/notepad.pro b/examples/widgets/tutorials/notepad/notepad.pro
index 6451f22735..efe16fc2a2 100644
--- a/examples/widgets/tutorials/notepad/notepad.pro
+++ b/examples/widgets/tutorials/notepad/notepad.pro
@@ -1,6 +1,8 @@
TEMPLATE = app
TARGET = notepad
+QT += widgets
+
qtHaveModule(printsupport): QT += printsupport
requires(qtConfig(fontdialog))
diff --git a/examples/widgets/widgets/imageviewer/imageviewer.cpp b/examples/widgets/widgets/imageviewer/imageviewer.cpp
index 70a4cda984..1ed55ca6cb 100644
--- a/examples/widgets/widgets/imageviewer/imageviewer.cpp
+++ b/examples/widgets/widgets/imageviewer/imageviewer.cpp
@@ -69,10 +69,11 @@
#include <QStatusBar>
#if defined(QT_PRINTSUPPORT_LIB)
-#include <QtPrintSupport/qtprintsupportglobal.h>
-#if QT_CONFIG(printdialog)
-#include <QPrintDialog>
-#endif
+# include <QtPrintSupport/qtprintsupportglobal.h>
+
+# if QT_CONFIG(printdialog)
+# include <QPrintDialog>
+# endif
#endif
//! [0]
diff --git a/examples/widgets/widgets/imageviewer/imageviewer.h b/examples/widgets/widgets/imageviewer/imageviewer.h
index 49c7ac205b..9c8388d470 100644
--- a/examples/widgets/widgets/imageviewer/imageviewer.h
+++ b/examples/widgets/widgets/imageviewer/imageviewer.h
@@ -53,8 +53,12 @@
#include <QMainWindow>
#include <QImage>
-#ifndef QT_NO_PRINTER
-#include <QPrinter>
+#if defined(QT_PRINTSUPPORT_LIB)
+# include <QtPrintSupport/qtprintsupportglobal.h>
+
+# if QT_CONFIG(printer)
+# include <QPrinter>
+# endif
#endif
QT_BEGIN_NAMESPACE
@@ -100,7 +104,7 @@ private:
QScrollArea *scrollArea;
double scaleFactor = 1;
-#ifndef QT_NO_PRINTER
+#if defined(QT_PRINTSUPPORT_LIB) && QT_CONFIG(printer)
QPrinter printer;
#endif
diff --git a/src/corelib/itemmodels/qsortfilterproxymodel.cpp b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
index 61d37d5062..122b95ed57 100644
--- a/src/corelib/itemmodels/qsortfilterproxymodel.cpp
+++ b/src/corelib/itemmodels/qsortfilterproxymodel.cpp
@@ -1949,8 +1949,9 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved(
example.)
If you are working with large amounts of filtering and have to invoke
- invalidateFilter() repeatedly, using reset() may be more efficient,
- depending on the implementation of your model. However, reset() returns the
+ invalidateFilter() repeatedly, using beginResetModel() / endResetModel() may
+ be more efficient, depending on the implementation of your model. However,
+ beginResetModel() / endResetModel() returns the
proxy model to its original state, losing selection information, and will
cause the proxy model to be repopulated.
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index 356a675517..9fc0659cf2 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -589,7 +589,8 @@ QMetaTypeComparatorRegistry;
typedef QMetaTypeFunctionRegistry<QtPrivate::AbstractDebugStreamFunction,int>
QMetaTypeDebugStreamRegistry;
-Q_STATIC_ASSERT(std::is_pod<QMetaTypeInterface>::value);
+Q_STATIC_ASSERT(std::is_trivial<QMetaTypeInterface>::value);
+Q_STATIC_ASSERT(std::is_standard_layout<QMetaTypeInterface>::value);
Q_DECLARE_TYPEINFO(QCustomTypeInfo, Q_MOVABLE_TYPE);
Q_GLOBAL_STATIC(QVector<QCustomTypeInfo>, customTypes)
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 18f10c9b43..9a6a69676d 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -389,17 +389,12 @@ QObject *QFactoryLoader::instance(int index) const
QMutexLocker lock(&d->mutex);
if (index < d->libraryList.size()) {
QLibraryPrivate *library = d->libraryList.at(index);
- if (library->instance || library->loadPlugin()) {
- if (!library->inst)
- library->inst = library->instance();
- QObject *obj = library->inst.data();
- if (obj) {
- if (!obj->parent())
- obj->moveToThread(QCoreApplicationPrivate::mainThread());
- return obj;
- }
+ if (QObject *obj = library->pluginInstance()) {
+ if (!obj->parent())
+ obj->moveToThread(QCoreApplicationPrivate::mainThread());
+ return obj;
}
- return 0;
+ return nullptr;
}
index -= d->libraryList.size();
lock.unlock();
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index eeaa3c18ec..ddb053c26f 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -407,7 +407,7 @@ inline void QLibraryStore::cleanup()
QLibraryPrivate *lib = it.value();
if (lib->libraryRefCount.loadRelaxed() == 1) {
if (lib->libraryUnloadCount.loadRelaxed() > 0) {
- Q_ASSERT(lib->pHnd);
+ Q_ASSERT(lib->pHnd.loadRelaxed());
lib->libraryUnloadCount.storeRelaxed(1);
#ifdef __GLIBC__
// glibc has a bug in unloading from global destructors
@@ -498,8 +498,7 @@ inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib)
}
QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints)
- : pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0),
- libraryRefCount(0), libraryUnloadCount(0), pluginState(MightBeAPlugin)
+ : fileName(canonicalFileName), fullVersion(version), pluginState(MightBeAPlugin)
{
loadHintsInt.storeRelaxed(loadHints);
if (canonicalFileName.isEmpty())
@@ -519,7 +518,7 @@ QLibraryPrivate::~QLibraryPrivate()
void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
{
// if the library is already loaded, we can't change the load hints
- if (pHnd)
+ if (pHnd.loadRelaxed())
return;
loadHintsInt.storeRelaxed(lh);
@@ -527,7 +526,7 @@ void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
{
- if (!pHnd)
+ if (!pHnd.loadRelaxed())
return 0;
return resolve_sys(symbol);
}
@@ -539,9 +538,36 @@ void QLibraryPrivate::setLoadHints(QLibrary::LoadHints lh)
mergeLoadHints(lh);
}
+QObject *QLibraryPrivate::pluginInstance()
+{
+ // first, check if the instance is cached and hasn't been deleted
+ QObject *obj = (QMutexLocker(&mutex), inst.data());
+ if (obj)
+ return obj;
+
+ // We need to call the plugin's factory function. Is that cached?
+ // skip increasing the reference count (why? -Thiago)
+ QtPluginInstanceFunction factory = instanceFactory.loadAcquire();
+ if (!factory)
+ factory = loadPlugin();
+
+ if (!factory)
+ return nullptr;
+
+ obj = factory();
+
+ // cache again
+ QMutexLocker locker(&mutex);
+ if (inst)
+ obj = inst;
+ else
+ inst = obj;
+ return obj;
+}
+
bool QLibraryPrivate::load()
{
- if (pHnd) {
+ if (pHnd.loadRelaxed()) {
libraryUnloadCount.ref();
return true;
}
@@ -550,7 +576,9 @@ bool QLibraryPrivate::load()
Q_TRACE(QLibraryPrivate_load_entry, fileName);
+ mutex.lock();
bool ret = load_sys();
+ mutex.unlock();
if (qt_debug_component()) {
if (ret) {
qDebug() << "loaded library" << fileName;
@@ -573,9 +601,10 @@ bool QLibraryPrivate::load()
bool QLibraryPrivate::unload(UnloadFlag flag)
{
- if (!pHnd)
+ if (!pHnd.loadRelaxed())
return false;
if (libraryUnloadCount.loadRelaxed() > 0 && !libraryUnloadCount.deref()) { // only unload if ALL QLibrary instance wanted to
+ QMutexLocker locker(&mutex);
delete inst.data();
if (flag == NoUnloadSys || unload_sys()) {
if (qt_debug_component())
@@ -584,12 +613,13 @@ bool QLibraryPrivate::unload(UnloadFlag flag)
//when the library is unloaded, we release the reference on it so that 'this'
//can get deleted
libraryRefCount.deref();
- pHnd = 0;
- instance = 0;
+ pHnd.storeRelaxed(nullptr);
+ instanceFactory.storeRelaxed(nullptr);
+ return true;
}
}
- return (pHnd == 0);
+ return false;
}
void QLibraryPrivate::release()
@@ -597,22 +627,23 @@ void QLibraryPrivate::release()
QLibraryStore::releaseLibrary(this);
}
-bool QLibraryPrivate::loadPlugin()
+QtPluginInstanceFunction QLibraryPrivate::loadPlugin()
{
- if (instance) {
+ if (auto ptr = instanceFactory.loadAcquire()) {
libraryUnloadCount.ref();
- return true;
+ return ptr;
}
if (pluginState == IsNotAPlugin)
- return false;
+ return nullptr;
if (load()) {
- instance = (QtPluginInstanceFunction)resolve("qt_plugin_instance");
- return instance;
+ auto ptr = reinterpret_cast<QtPluginInstanceFunction>(resolve("qt_plugin_instance"));
+ instanceFactory.storeRelease(ptr); // two threads may store the same value
+ return ptr;
}
if (qt_debug_component())
qWarning() << "QLibraryPrivate::loadPlugin failed on" << fileName << ":" << errorString;
pluginState = IsNotAPlugin;
- return false;
+ return nullptr;
}
/*!
@@ -719,6 +750,7 @@ bool QLibraryPrivate::isPlugin()
void QLibraryPrivate::updatePluginState()
{
+ QMutexLocker locker(&mutex);
errorString.clear();
if (pluginState != MightBeAPlugin)
return;
@@ -739,7 +771,7 @@ void QLibraryPrivate::updatePluginState()
}
#endif
- if (!pHnd) {
+ if (!pHnd.loadRelaxed()) {
// scan for the plugin metadata without loading
success = findPatternUnloaded(fileName, this);
} else {
@@ -803,7 +835,7 @@ bool QLibrary::load()
if (!d)
return false;
if (did_load)
- return d->pHnd;
+ return d->pHnd.loadRelaxed();
did_load = true;
return d->load();
}
@@ -839,7 +871,7 @@ bool QLibrary::unload()
*/
bool QLibrary::isLoaded() const
{
- return d && d->pHnd;
+ return d && d->pHnd.loadRelaxed();
}
@@ -950,8 +982,10 @@ void QLibrary::setFileName(const QString &fileName)
QString QLibrary::fileName() const
{
- if (d)
+ if (d) {
+ QMutexLocker locker(&d->mutex);
return d->qualifiedFileName.isEmpty() ? d->fileName : d->qualifiedFileName;
+ }
return QString();
}
@@ -1092,7 +1126,12 @@ QFunctionPointer QLibrary::resolve(const QString &fileName, const QString &versi
*/
QString QLibrary::errorString() const
{
- return (!d || d->errorString.isEmpty()) ? tr("Unknown error") : d->errorString;
+ QString str;
+ if (d) {
+ QMutexLocker locker(&d->mutex);
+ str = d->errorString;
+ }
+ return str.isEmpty() ? tr("Unknown error") : str;
}
/*!
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index db5afac98e..d756126c64 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -54,10 +54,10 @@
#include <QtCore/private/qglobal_p.h>
#include "QtCore/qlibrary.h"
+#include "QtCore/qmutex.h"
#include "QtCore/qpointer.h"
#include "QtCore/qstringlist.h"
#include "QtCore/qplugin.h"
-#include "QtCore/qsharedpointer.h"
#ifdef Q_OS_WIN
# include "QtCore/qt_windows.h"
#endif
@@ -72,21 +72,18 @@ class QLibraryStore;
class QLibraryPrivate
{
public:
-
#ifdef Q_OS_WIN
- HINSTANCE
+ using Handle = HINSTANCE;
#else
- void *
+ using Handle = void *;
#endif
- pHnd;
-
enum UnloadFlag { UnloadSys, NoUnloadSys };
- QString fileName, qualifiedFileName;
- QString fullVersion;
+ const QString fileName;
+ const QString fullVersion;
bool load();
- bool loadPlugin(); // loads and resolves instance
+ QtPluginInstanceFunction loadPlugin(); // loads and resolves instance
bool unload(UnloadFlag flag = UnloadSys);
void release();
QFunctionPointer resolve(const char *);
@@ -94,17 +91,22 @@ public:
QLibrary::LoadHints loadHints() const
{ return QLibrary::LoadHints(loadHintsInt.loadRelaxed()); }
void setLoadHints(QLibrary::LoadHints lh);
+ QObject *pluginInstance();
static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString(),
QLibrary::LoadHints loadHints = nullptr);
static QStringList suffixes_sys(const QString &fullVersion);
static QStringList prefixes_sys();
- QPointer<QObject> inst;
- QtPluginInstanceFunction instance;
- QJsonObject metaData;
+ QAtomicPointer<std::remove_pointer<QtPluginInstanceFunction>::type> instanceFactory;
+ QAtomicPointer<std::remove_pointer<Handle>::type> pHnd;
+ // the mutex protects the fields below
+ QMutex mutex;
+ QPointer<QObject> inst; // used by QFactoryLoader
+ QJsonObject metaData;
QString errorString;
+ QString qualifiedFileName;
void updatePluginState();
bool isPlugin();
diff --git a/src/corelib/plugin/qlibrary_unix.cpp b/src/corelib/plugin/qlibrary_unix.cpp
index 135b82cd37..29813e5863 100644
--- a/src/corelib/plugin/qlibrary_unix.cpp
+++ b/src/corelib/plugin/qlibrary_unix.cpp
@@ -214,8 +214,9 @@ bool QLibraryPrivate::load_sys()
#endif
bool retry = true;
- for(int prefix = 0; retry && !pHnd && prefix < prefixes.size(); prefix++) {
- for(int suffix = 0; retry && !pHnd && suffix < suffixes.size(); suffix++) {
+ Handle hnd = nullptr;
+ for (int prefix = 0; retry && !hnd && prefix < prefixes.size(); prefix++) {
+ for (int suffix = 0; retry && !hnd && suffix < suffixes.size(); suffix++) {
if (!prefixes.at(prefix).isEmpty() && name.startsWith(prefixes.at(prefix)))
continue;
if (path.isEmpty() && prefixes.at(prefix).contains(QLatin1Char('/')))
@@ -232,7 +233,7 @@ bool QLibraryPrivate::load_sys()
attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
}
- pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
+ hnd = dlopen(QFile::encodeName(attempt), dlFlags);
#ifdef Q_OS_ANDROID
if (!pHnd) {
auto attemptFromBundle = attempt;
@@ -248,7 +249,7 @@ bool QLibraryPrivate::load_sys()
}
#endif
- if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
+ if (!hnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
// We only want to continue if dlopen failed due to that the shared library did not exist.
// However, we are only able to apply this check for absolute filenames (since they are
// not influenced by the content of LD_LIBRARY_PATH, /etc/ld.so.cache, DT_RPATH etc...)
@@ -259,7 +260,7 @@ bool QLibraryPrivate::load_sys()
}
#ifdef Q_OS_MAC
- if (!pHnd) {
+ if (!hnd) {
QByteArray utf8Bundle = fileName.toUtf8();
QCFType<CFURLRef> bundleUrl = CFURLCreateFromFileSystemRepresentation(NULL, reinterpret_cast<const UInt8*>(utf8Bundle.data()), utf8Bundle.length(), true);
QCFType<CFBundleRef> bundle = CFBundleCreate(NULL, bundleUrl);
@@ -268,23 +269,24 @@ bool QLibraryPrivate::load_sys()
char executableFile[FILENAME_MAX];
CFURLGetFileSystemRepresentation(url, true, reinterpret_cast<UInt8*>(executableFile), FILENAME_MAX);
attempt = QString::fromUtf8(executableFile);
- pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
+ hnd = dlopen(QFile::encodeName(attempt), dlFlags);
}
}
#endif
- if (!pHnd) {
+ if (!hnd) {
errorString = QLibrary::tr("Cannot load library %1: %2").arg(fileName, qdlerror());
}
- if (pHnd) {
+ if (hnd) {
qualifiedFileName = attempt;
errorString.clear();
}
- return (pHnd != 0);
+ pHnd.storeRelaxed(hnd);
+ return (hnd != nullptr);
}
bool QLibraryPrivate::unload_sys()
{
- if (dlclose(pHnd)) {
+ if (dlclose(pHnd.loadAcquire())) {
#if defined (Q_OS_QNX) // Workaround until fixed in QNX; fixes crash in
char *error = dlerror(); // QtDeclarative auto test "qqmlenginecleanup" for instance
if (!qstrcmp(error, "Shared objects still referenced")) // On QNX that's only "informative"
@@ -316,13 +318,7 @@ Q_CORE_EXPORT QFunctionPointer qt_mac_resolve_sys(void *handle, const char *symb
QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
{
- QFunctionPointer address = QFunctionPointer(dlsym(pHnd, symbol));
- if (!address) {
- errorString = QLibrary::tr("Cannot resolve symbol \"%1\" in %2: %3").arg(
- QString::fromLatin1(symbol), fileName, qdlerror());
- } else {
- errorString.clear();
- }
+ QFunctionPointer address = QFunctionPointer(dlsym(pHnd.loadAcquire(), symbol));
return address;
}
diff --git a/src/corelib/plugin/qlibrary_win.cpp b/src/corelib/plugin/qlibrary_win.cpp
index 05a93d467e..000bf76276 100644
--- a/src/corelib/plugin/qlibrary_win.cpp
+++ b/src/corelib/plugin/qlibrary_win.cpp
@@ -95,26 +95,27 @@ bool QLibraryPrivate::load_sys()
attempts.prepend(QDir::rootPath() + fileName);
#endif
+ Handle hnd = nullptr;
for (const QString &attempt : qAsConst(attempts)) {
#ifndef Q_OS_WINRT
- pHnd = LoadLibrary(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(attempt).utf16()));
+ hnd = LoadLibrary(reinterpret_cast<const wchar_t*>(QDir::toNativeSeparators(attempt).utf16()));
#else // Q_OS_WINRT
QString path = QDir::toNativeSeparators(QDir::current().relativeFilePath(attempt));
- pHnd = LoadPackagedLibrary(reinterpret_cast<LPCWSTR>(path.utf16()), 0);
- if (pHnd)
+ hnd = LoadPackagedLibrary(reinterpret_cast<LPCWSTR>(path.utf16()), 0);
+ if (hnd)
qualifiedFileName = attempt;
#endif // !Q_OS_WINRT
// If we have a handle or the last error is something other than "unable
// to find the module", then bail out
- if (pHnd || ::GetLastError() != ERROR_MOD_NOT_FOUND)
+ if (hnd || ::GetLastError() != ERROR_MOD_NOT_FOUND)
break;
}
#ifndef Q_OS_WINRT
SetErrorMode(oldmode);
#endif
- if (!pHnd) {
+ if (!hnd) {
errorString = QLibrary::tr("Cannot load library %1: %2").arg(
QDir::toNativeSeparators(fileName), qt_error_string());
} else {
@@ -123,7 +124,7 @@ bool QLibraryPrivate::load_sys()
#ifndef Q_OS_WINRT
wchar_t buffer[MAX_PATH];
- ::GetModuleFileName(pHnd, buffer, MAX_PATH);
+ ::GetModuleFileName(hnd, buffer, MAX_PATH);
QString moduleFileName = QString::fromWCharArray(buffer);
moduleFileName.remove(0, 1 + moduleFileName.lastIndexOf(QLatin1Char('\\')));
@@ -138,19 +139,20 @@ bool QLibraryPrivate::load_sys()
HMODULE hmod;
bool ok = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_PIN |
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
- reinterpret_cast<const wchar_t *>(pHnd),
+ reinterpret_cast<const wchar_t *>(hnd),
&hmod);
- Q_ASSERT(!ok || hmod == pHnd);
+ Q_ASSERT(!ok || hmod == hnd);
Q_UNUSED(ok);
}
#endif // !Q_OS_WINRT
}
- return (pHnd != 0);
+ pHnd.storeRelaxed(hnd);
+ return (pHnd != nullptr);
}
bool QLibraryPrivate::unload_sys()
{
- if (!FreeLibrary(pHnd)) {
+ if (!FreeLibrary(pHnd.loadAcquire())) {
errorString = QLibrary::tr("Cannot unload library %1: %2").arg(
QDir::toNativeSeparators(fileName), qt_error_string());
return false;
@@ -161,13 +163,7 @@ bool QLibraryPrivate::unload_sys()
QFunctionPointer QLibraryPrivate::resolve_sys(const char* symbol)
{
- FARPROC address = GetProcAddress(pHnd, symbol);
- if (!address) {
- errorString = QLibrary::tr("Cannot resolve symbol \"%1\" in %2: %3").arg(
- QString::fromLatin1(symbol), QDir::toNativeSeparators(fileName), qt_error_string());
- } else {
- errorString.clear();
- }
+ FARPROC address = GetProcAddress(pHnd.loadAcquire(), symbol);
return QFunctionPointer(address);
}
QT_END_NAMESPACE
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index dac8502dae..0e12793d5e 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -196,9 +196,7 @@ QObject *QPluginLoader::instance()
{
if (!isLoaded() && !load())
return 0;
- if (!d->inst && d->instance)
- d->inst = d->instance();
- return d->inst.data();
+ return d->pluginInstance();
}
/*!
@@ -233,7 +231,7 @@ bool QPluginLoader::load()
if (!d || d->fileName.isEmpty())
return false;
if (did_load)
- return d->pHnd && d->instance;
+ return d->pHnd && d->instanceFactory.loadAcquire();
if (!d->isPlugin())
return false;
did_load = true;
@@ -275,7 +273,7 @@ bool QPluginLoader::unload()
*/
bool QPluginLoader::isLoaded() const
{
- return d && d->pHnd && d->instance;
+ return d && d->pHnd && d->instanceFactory.loadRelaxed();
}
#if defined(QT_SHARED)
diff --git a/src/corelib/serialization/qcborvalue_p.h b/src/corelib/serialization/qcborvalue_p.h
index 48818e4c63..a74ac2ba10 100644
--- a/src/corelib/serialization/qcborvalue_p.h
+++ b/src/corelib/serialization/qcborvalue_p.h
@@ -115,7 +115,8 @@ struct ByteData
QStringView asStringView() const{ return QStringView(utf16(), len / 2); }
QString asQStringRaw() const { return QString::fromRawData(utf16(), len / 2); }
};
-Q_STATIC_ASSERT(std::is_pod<ByteData>::value);
+Q_STATIC_ASSERT(std::is_trivial<ByteData>::value);
+Q_STATIC_ASSERT(std::is_standard_layout<ByteData>::value);
} // namespace QtCbor
Q_DECLARE_TYPEINFO(QtCbor::Element, Q_PRIMITIVE_TYPE);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 0a4277c118..9cb851a7a2 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1666,7 +1666,7 @@ void QWindow::setGeometry(const QRect &rect)
if (newScreen && isTopLevel())
nativeRect = QHighDpi::toNativePixels(rect, newScreen);
else
- nativeRect = QHighDpi::toNativePixels(rect, this);
+ nativeRect = QHighDpi::toNativeLocalPosition(rect, newScreen);
d->platformWindow->setGeometry(nativeRect);
} else {
d->geometry = rect;
@@ -1717,8 +1717,12 @@ QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) const
QRect QWindow::geometry() const
{
Q_D(const QWindow);
- if (d->platformWindow)
- return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this);
+ if (d->platformWindow) {
+ const auto nativeGeometry = d->platformWindow->geometry();
+ return isTopLevel()
+ ? QHighDpi::fromNativePixels(nativeGeometry, this)
+ : QHighDpi::fromNativeLocalPosition(nativeGeometry, this);
+ }
return d->geometry;
}
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 8457282bed..8f2927901a 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -296,14 +296,21 @@ QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow
, window(window)
, newGeometry(newGeometry)
{
- if (const QPlatformWindow *pw = window->handle())
- requestedGeometry = QHighDpi::fromNativePixels(pw->QPlatformWindow::geometry(), window);
+ if (const QPlatformWindow *pw = window->handle()) {
+ const auto nativeGeometry = pw->QPlatformWindow::geometry();
+ requestedGeometry = window->isTopLevel()
+ ? QHighDpi::fromNativePixels(nativeGeometry, window)
+ : QHighDpi::fromNativeLocalPosition(nativeGeometry, window);
+ }
}
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
{
Q_ASSERT(window);
- QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, QHighDpi::fromNativePixels(newRect, window));
+ const auto newRectDi = window->isTopLevel()
+ ? QHighDpi::fromNativePixels(newRect, window)
+ : QHighDpi::fromNativeLocalPosition(newRect, window);
+ auto e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, newRectDi);
if (window->handle()) {
// Persist the new geometry so that QWindow::geometry() can be queried in the resize event
window->handle()->QPlatformWindow::setGeometry(newRect);
diff --git a/src/gui/text/qtextmarkdownimporter.cpp b/src/gui/text/qtextmarkdownimporter.cpp
index 7e18a10895..5e75e7816b 100644
--- a/src/gui/text/qtextmarkdownimporter.cpp
+++ b/src/gui/text/qtextmarkdownimporter.cpp
@@ -577,7 +577,10 @@ void QTextMarkdownImporter::insertBlock()
QTextBlockFormat blockFormat;
if (!m_listStack.isEmpty() && !m_needsInsertList && m_listItem) {
QTextList *list = m_listStack.top();
- blockFormat = list->item(list->count() - 1).blockFormat();
+ if (list)
+ blockFormat = list->item(list->count() - 1).blockFormat();
+ else
+ qWarning() << "attempted to insert into a list that no longer exists";
}
if (m_blockQuoteDepth) {
blockFormat.setProperty(QTextFormat::BlockQuoteLevel, m_blockQuoteDepth);
@@ -607,7 +610,7 @@ void QTextMarkdownImporter::insertBlock()
}
if (m_needsInsertList) {
m_listStack.push(m_cursor->createList(m_listFormat));
- } else if (!m_listStack.isEmpty() && m_listItem) {
+ } else if (!m_listStack.isEmpty() && m_listItem && m_listStack.top()) {
m_listStack.top()->add(m_cursor->block());
}
m_needsInsertList = false;
diff --git a/src/gui/text/qtextmarkdownimporter_p.h b/src/gui/text/qtextmarkdownimporter_p.h
index f450da5eb3..f12b725d8e 100644
--- a/src/gui/text/qtextmarkdownimporter_p.h
+++ b/src/gui/text/qtextmarkdownimporter_p.h
@@ -56,6 +56,7 @@
#include <QtGui/qpalette.h>
#include <QtGui/qtextdocument.h>
#include <QtGui/qtextlist.h>
+#include <QtCore/qpointer.h>
#include <QtCore/qstack.h>
QT_BEGIN_NAMESPACE
@@ -113,7 +114,7 @@ private:
#endif
QString m_blockCodeLanguage;
QVector<int> m_nonEmptyTableCells; // in the current row
- QStack<QTextList *> m_listStack;
+ QStack<QPointer<QTextList>> m_listStack;
QStack<QTextCharFormat> m_spanFormatStack;
QFont m_monoFont;
QPalette m_palette;
diff --git a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
index f601a196ca..c2413c131d 100644
--- a/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
+++ b/src/platformsupport/devicediscovery/qdevicediscovery_udev.cpp
@@ -46,7 +46,11 @@
#include <QSocketNotifier>
#include <QLoggingCategory>
+#ifdef Q_OS_FREEBSD
+#include <dev/evdev/input.h>
+#else
#include <linux/input.h>
+#endif
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 09117f663d..d37b405db8 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -334,7 +334,9 @@ QPlatformWindow *QWindowsIntegration::createPlatformWindow(QWindow *window) cons
QWindowsWindowData requested;
requested.flags = window->flags();
- requested.geometry = QHighDpi::toNativePixels(window->geometry(), window);
+ requested.geometry = window->isTopLevel()
+ ? QHighDpi::toNativePixels(window->geometry(), window)
+ : QHighDpi::toNativeLocalPosition(window->geometry(), window);
// Apply custom margins (see QWindowsWindow::setCustomMargins())).
const QVariant customMarginsV = window->property("_q_windowsCustomMargins");
if (customMarginsV.isValid())
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index ecb73cb90b..d366564dd6 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -122,6 +122,7 @@ static const char *xcb_atomnames = {
"_NET_WM_STATE_MODAL\0"
"_NET_WM_STATE_STAYS_ON_TOP\0"
"_NET_WM_STATE_DEMANDS_ATTENTION\0"
+ "_NET_WM_STATE_HIDDEN\0"
"_NET_WM_USER_TIME\0"
"_NET_WM_USER_TIME_WINDOW\0"
diff --git a/src/plugins/platforms/xcb/qxcbatom.h b/src/plugins/platforms/xcb/qxcbatom.h
index 233d2eadb7..80b5887395 100644
--- a/src/plugins/platforms/xcb/qxcbatom.h
+++ b/src/plugins/platforms/xcb/qxcbatom.h
@@ -123,6 +123,7 @@ public:
_NET_WM_STATE_MODAL,
_NET_WM_STATE_STAYS_ON_TOP,
_NET_WM_STATE_DEMANDS_ATTENTION,
+ _NET_WM_STATE_HIDDEN,
_NET_WM_USER_TIME,
_NET_WM_USER_TIME_WINDOW,
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index cfe048d5c4..a5974ec36e 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -276,7 +276,9 @@ void QXcbWindow::create()
QXcbScreen *currentScreen = xcbScreen();
QXcbScreen *platformScreen = parent() ? parentScreen() : initialScreen();
- QRect rect = QHighDpi::toNativePixels(window()->geometry(), platformScreen);
+ QRect rect = parent()
+ ? QHighDpi::toNativeLocalPosition(window()->geometry(), platformScreen)
+ : QHighDpi::toNativePixels(window()->geometry(), platformScreen);
if (type == Qt::Desktop) {
m_window = platformScreen->root();
@@ -905,6 +907,8 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates()
result |= NetWmStateStaysOnTop;
if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)))
result |= NetWmStateDemandsAttention;
+ if (statesEnd != std::find(states, statesEnd, atom(QXcbAtom::_NET_WM_STATE_HIDDEN)))
+ result |= NetWmStateHidden;
} else {
qCDebug(lcQpaXcb, "getting net wm state (%x), empty\n", m_window);
}
@@ -1076,6 +1080,9 @@ void QXcbWindow::setNetWmStateOnUnmappedWindow()
states |= NetWmStateBelow;
}
+ if (window()->windowStates() & Qt::WindowMinimized)
+ states |= NetWmStateHidden;
+
if (window()->windowStates() & Qt::WindowFullScreen)
states |= NetWmStateFullScreen;
@@ -1109,6 +1116,8 @@ void QXcbWindow::setNetWmStateOnUnmappedWindow()
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE));
if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW));
+ if (states & NetWmStateHidden && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_HIDDEN)))
+ atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_HIDDEN));
if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)))
atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN));
if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)))
@@ -2217,10 +2226,16 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
|| (data[0] == XCB_ICCCM_WM_STATE_WITHDRAWN && m_minimized));
}
}
- if (m_minimized)
- newState = Qt::WindowMinimized;
const NetWmStates states = netWmStates();
+ // _NET_WM_STATE_HIDDEN should be set by the Window Manager to indicate that a window would
+ // not be visible on the screen if its desktop/viewport were active and its coordinates were
+ // within the screen bounds. The canonical example is that minimized windows should be in
+ // the _NET_WM_STATE_HIDDEN state.
+ if (m_minimized && (!connection()->wmSupport()->isSupportedByWM(NetWmStateHidden)
+ || states.testFlag(NetWmStateHidden)))
+ newState = Qt::WindowMinimized;
+
if (states & NetWmStateFullScreen)
newState |= Qt::WindowFullScreen;
if ((states & NetWmStateMaximizedHorz) && (states & NetWmStateMaximizedVert))
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index a808437c5a..b84250d109 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -68,7 +68,8 @@ public:
NetWmStateMaximizedVert = 0x10,
NetWmStateModal = 0x20,
NetWmStateStaysOnTop = 0x40,
- NetWmStateDemandsAttention = 0x80
+ NetWmStateDemandsAttention = 0x80,
+ NetWmStateHidden = 0x100
};
Q_DECLARE_FLAGS(NetWmStates, NetWmState)
diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp
index 1212c410ff..92fd6471a8 100644
--- a/src/tools/uic/cpp/cppwriteinitialization.cpp
+++ b/src/tools/uic/cpp/cppwriteinitialization.cpp
@@ -546,12 +546,19 @@ void WriteInitialization::acceptUI(DomUI *node)
m_output << m_option.indent << language::endFunctionDefinition("setupUi");
- if (!m_mainFormUsedInRetranslateUi && language::language() == Language::Cpp) {
- // Mark varName as unused to avoid compiler warnings.
- m_refreshInitialization += m_indent;
- m_refreshInitialization += QLatin1String("(void)");
- m_refreshInitialization += varName ;
- m_refreshInitialization += language::eol;
+ if (!m_mainFormUsedInRetranslateUi) {
+ if (language::language() == Language::Cpp) {
+ // Mark varName as unused to avoid compiler warnings.
+ m_refreshInitialization += m_indent;
+ m_refreshInitialization += QLatin1String("(void)");
+ m_refreshInitialization += varName ;
+ m_refreshInitialization += language::eol;
+ } else if (language::language() == Language::Python) {
+ // output a 'pass' to have an empty function
+ m_refreshInitialization += m_indent;
+ m_refreshInitialization += QLatin1String("pass");
+ m_refreshInitialization += language::eol;
+ }
}
m_output << m_option.indent
diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp
index 04151c3f31..04331527f9 100644
--- a/src/xml/dom/qdom.cpp
+++ b/src/xml/dom/qdom.cpp
@@ -62,6 +62,7 @@
#include <qshareddata.h>
#include <qdebug.h>
#include <stdio.h>
+#include <limits>
QT_BEGIN_NAMESPACE
@@ -4866,7 +4867,7 @@ void QDomElement::setAttribute(const QString& name, float value)
if (!impl)
return;
QString x;
- x.setNum(value);
+ x.setNum(value, 'g', 8);
IMPL->setAttribute(name, x);
}
@@ -4880,7 +4881,7 @@ void QDomElement::setAttribute(const QString& name, double value)
if (!impl)
return;
QString x;
- x.setNum(value);
+ x.setNum(value, 'g', 17);
IMPL->setAttribute(name, x);
}
@@ -5049,7 +5050,7 @@ void QDomElement::setAttributeNS(const QString nsURI, const QString& qName, doub
if (!impl)
return;
QString x;
- x.setNum(value);
+ x.setNum(value, 'g', 17);
IMPL->setAttributeNS(nsURI, qName, x);
}
diff --git a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
index 35c5e7cb75..db53c3f20c 100644
--- a/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
+++ b/tests/auto/corelib/kernel/qdeadlinetimer/tst_qdeadlinetimer.cpp
@@ -573,12 +573,32 @@ void tst_QDeadlineTimer::stdchrono()
QCOMPARE(deadline.remainingTimeAsDuration(), nanoseconds::zero());
+ /*
+ Call QTest::qSleep, and return true if the time actually slept is
+ within \a deviationPercent percent of the requested sleep time.
+ Otherwise, return false, in which case the test should to abort.
+ */
+ auto sleepHelper = [](int ms, int deviationPercent = 10) -> bool {
+ auto before = steady_clock::now();
+ QTest::qSleep(ms);
+ auto after = steady_clock::now();
+ auto diff = duration_cast<milliseconds>(after - before).count();
+ bool inRange = qAbs(diff - ms) < ms * deviationPercent/100.0;
+ if (!inRange)
+ qWarning() << "sleeping" << diff << "instead of" << ms << inRange;
+ return inRange;
+ };
+
auto steady_before = steady_clock::now();
auto system_before = system_clock::now();
- QTest::qSleep(minResolution);
+ if (!sleepHelper(minResolution))
+ QSKIP("Slept too long");
auto now = QDeadlineTimer::current(timerType);
- QTest::qSleep(minResolution);
+ auto steady_reference = steady_clock::now();
+ auto system_reference = system_clock::now();
+ if (!sleepHelper(minResolution))
+ QSKIP("Slept too long");
auto sampling_start = steady_clock::now();
auto steady_deadline = now.deadline<steady_clock>();
@@ -599,35 +619,33 @@ void tst_QDeadlineTimer::stdchrono()
}
{
- auto diff = duration_cast<milliseconds>(steady_after - steady_deadline);
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
+ auto reference = duration_cast<milliseconds>(steady_after - steady_reference).count();
+ auto diff = duration_cast<milliseconds>(steady_after - steady_deadline).count();
+ QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
QDeadlineTimer dt_after(steady_after, timerType);
QVERIFY2(now < dt_after,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
- diff = duration_cast<milliseconds>(steady_deadline - steady_before);
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
+ reference = duration_cast<milliseconds>(steady_reference - steady_before).count();
+ diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
+ QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff)));
QDeadlineTimer dt_before(steady_before, timerType);
QVERIFY2(now > dt_before,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
}
{
- auto diff = duration_cast<milliseconds>(system_after - system_deadline);
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
- QDeadlineTimer dt_after(system_after, timerType);
+ auto reference = duration_cast<milliseconds>(system_after - system_reference).count();
+ auto diff = duration_cast<milliseconds>(system_after - system_deadline).count();
+ QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_after(system_after, timerType);
QVERIFY2(now < dt_after,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; after = " + QLocale().toString(dt_after.deadlineNSecs())).toLatin1());
- diff = duration_cast<milliseconds>(system_deadline - system_before);
- QVERIFY2(diff.count() > minResolution/2, QByteArray::number(qint64(diff.count())));
- QVERIFY2(diff.count() < 3*minResolution/2, QByteArray::number(qint64(diff.count())));
- QDeadlineTimer dt_before(system_before, timerType);
+ reference = duration_cast<milliseconds>(system_reference - system_before).count();
+ diff = duration_cast<milliseconds>(steady_deadline - steady_before).count();
+ QVERIFY2(diff > reference * 0.9 && diff < reference*1.1, QByteArray::number(qint64(diff))); QDeadlineTimer dt_before(system_before, timerType);
QVERIFY2(now > dt_before,
("now = " + QLocale().toString(now.deadlineNSecs()) +
"; before = " + QLocale().toString(dt_before.deadlineNSecs())).toLatin1());
diff --git a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST b/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
deleted file mode 100644
index 2317cf886c..0000000000
--- a/tests/auto/corelib/kernel/qelapsedtimer/BLACKLIST
+++ /dev/null
@@ -1,3 +0,0 @@
-[elapsed]
-macos
-windows-10
diff --git a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
index e0d09b0813..50c4d9b467 100644
--- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
+++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
@@ -368,7 +368,7 @@ void tst_QLibrary::errorString_data()
QTest::newRow("bad load()") << (int)Load << QString("nosuchlib") << false << QString("Cannot load library nosuchlib: .*");
QTest::newRow("call errorString() on QLibrary with no d-pointer (crashtest)") << (int)(Load | DontSetFileName) << QString() << false << QString("Unknown error");
- QTest::newRow("bad resolve") << (int)Resolve << appDir + "/mylib" << false << QString("Cannot resolve symbol \"nosuchsymbol\" in \\S+: .*");
+ QTest::newRow("bad resolve") << (int)Resolve << appDir + "/mylib" << false << QString("Unknown error");
QTest::newRow("good resolve") << (int)Resolve << appDir + "/mylib" << true << QString("Unknown error");
#ifdef Q_OS_WIN
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20450.md b/tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20450.md
new file mode 100644
index 0000000000..d7005cb01e
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20450.md
@@ -0,0 +1,5 @@
+<t>ÿ
+* ÿ
+
+ ÿ
+* ÿ \ No newline at end of file
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20580.md b/tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20580.md
new file mode 100644
index 0000000000..22006f5876
--- /dev/null
+++ b/tests/auto/gui/text/qtextmarkdownimporter/data/fuzz20580.md
@@ -0,0 +1 @@
+| --:| <?`?><?|` \ No newline at end of file
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/qtextmarkdownimporter.pro b/tests/auto/gui/text/qtextmarkdownimporter/qtextmarkdownimporter.pro
index 7b7fb61244..f3818efbf7 100644
--- a/tests/auto/gui/text/qtextmarkdownimporter/qtextmarkdownimporter.pro
+++ b/tests/auto/gui/text/qtextmarkdownimporter/qtextmarkdownimporter.pro
@@ -5,5 +5,7 @@ SOURCES += tst_qtextmarkdownimporter.cpp
TESTDATA += \
data/thematicBreaks.md \
data/headingBulletsContinuations.md \
+ data/fuzz20450.md \
+ data/fuzz20580.md \
DEFINES += SRCDIR=\\\"$$PWD\\\"
diff --git a/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp b/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp
index 39a1370f6f..5eb04af696 100644
--- a/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp
+++ b/tests/auto/gui/text/qtextmarkdownimporter/tst_qtextmarkdownimporter.cpp
@@ -57,6 +57,8 @@ private slots:
void lists();
void avoidBlankLineAtBeginning_data();
void avoidBlankLineAtBeginning();
+ void pathological_data();
+ void pathological();
};
void tst_QTextMarkdownImporter::headingBulletsContinuations()
@@ -256,5 +258,27 @@ void tst_QTextMarkdownImporter::avoidBlankLineAtBeginning() // QTBUG-81060
QCOMPARE(i, expectedNumberOfParagraphs);
}
+void tst_QTextMarkdownImporter::pathological_data()
+{
+ QTest::addColumn<QString>("warning");
+ QTest::newRow("fuzz20450") << "attempted to insert into a list that no longer exists";
+ QTest::newRow("fuzz20580") << "";
+}
+
+void tst_QTextMarkdownImporter::pathological() // avoid crashing on crazy input
+{
+ QFETCH(QString, warning);
+ QString filename = QLatin1String("data/") + QTest::currentDataTag() + QLatin1String(".md");
+ QFile f(QFINDTESTDATA(filename));
+ QVERIFY(f.open(QFile::ReadOnly));
+#ifdef QT_NO_DEBUG
+ Q_UNUSED(warning)
+#else
+ if (!warning.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, warning.toLatin1());
+#endif
+ QTextDocument().setMarkdown(f.readAll());
+}
+
QTEST_MAIN(tst_QTextMarkdownImporter)
#include "tst_qtextmarkdownimporter.moc"
diff --git a/tests/auto/widgets/kernel/qwidget_window/BLACKLIST b/tests/auto/widgets/kernel/qwidget_window/BLACKLIST
index 39d7b695f6..d3bfaba433 100644
--- a/tests/auto/widgets/kernel/qwidget_window/BLACKLIST
+++ b/tests/auto/widgets/kernel/qwidget_window/BLACKLIST
@@ -2,7 +2,3 @@
# QTBUG-66345
opensuse-42.3
ubuntu-16.04
-[setWindowState]
-ubuntu-18.04
-rhel-7.6
-
diff --git a/tests/auto/xml/dom/qdom/tst_qdom.cpp b/tests/auto/xml/dom/qdom/tst_qdom.cpp
index 99639df5b0..229d2ba6e5 100644
--- a/tests/auto/xml/dom/qdom/tst_qdom.cpp
+++ b/tests/auto/xml/dom/qdom/tst_qdom.cpp
@@ -38,6 +38,7 @@
#include <QtTest/QtTest>
#include <QtXml>
#include <QVariant>
+#include <cmath>
QT_FORWARD_DECLARE_CLASS(QDomDocument)
QT_FORWARD_DECLARE_CLASS(QDomNode)
@@ -408,7 +409,9 @@ void tst_QDom::setGetAttributes()
const int intVal = std::numeric_limits<int>::min();
const uint uintVal = std::numeric_limits<uint>::max();
const float floatVal = 0.1234f;
- const double doubleVal = 0.1234;
+ const double doubleVal1 = 1./6.;
+ const double doubleVal2 = std::nextafter(doubleVal1, 1.);
+ const double doubleVal3 = std::nextafter(doubleVal2, 1.);
rootNode.setAttribute("qstringVal", qstringVal);
rootNode.setAttribute("qlonglongVal", qlonglongVal);
@@ -416,7 +419,9 @@ void tst_QDom::setGetAttributes()
rootNode.setAttribute("intVal", intVal);
rootNode.setAttribute("uintVal", uintVal);
rootNode.setAttribute("floatVal", floatVal);
- rootNode.setAttribute("doubleVal", doubleVal);
+ rootNode.setAttribute("doubleVal1", doubleVal1);
+ rootNode.setAttribute("doubleVal2", doubleVal2);
+ rootNode.setAttribute("doubleVal3", doubleVal3);
QDomElement nsNode = doc.createElement("NS");
rootNode.appendChild(nsNode);
@@ -426,7 +431,9 @@ void tst_QDom::setGetAttributes()
nsNode.setAttributeNS("namespace", "intVal", intVal);
nsNode.setAttributeNS("namespace", "uintVal", uintVal);
nsNode.setAttributeNS("namespace", "floatVal", floatVal); // not available atm
- nsNode.setAttributeNS("namespace", "doubleVal", doubleVal);
+ nsNode.setAttributeNS("namespace", "doubleVal1", doubleVal1);
+ nsNode.setAttributeNS("namespace", "doubleVal2", doubleVal2);
+ nsNode.setAttributeNS("namespace", "doubleVal3", doubleVal3);
bool bOk;
QCOMPARE(rootNode.attribute("qstringVal"), qstringVal);
@@ -440,8 +447,10 @@ void tst_QDom::setGetAttributes()
QVERIFY(bOk);
QCOMPARE(rootNode.attribute("floatVal").toFloat(&bOk), floatVal);
QVERIFY(bOk);
- QCOMPARE(rootNode.attribute("doubleVal").toDouble(&bOk), doubleVal);
- QVERIFY(bOk);
+
+ QVERIFY(rootNode.attribute("doubleVal1").toDouble(&bOk) == doubleVal1 && bOk);
+ QVERIFY(rootNode.attribute("doubleVal2").toDouble(&bOk) == doubleVal2 && bOk);
+ QVERIFY(rootNode.attribute("doubleVal3").toDouble(&bOk) == doubleVal3 && bOk);
QCOMPARE(nsNode.attributeNS("namespace", "qstringVal"), qstringVal);
QCOMPARE(nsNode.attributeNS("namespace", "qlonglongVal").toLongLong(&bOk), qlonglongVal);
@@ -454,8 +463,9 @@ void tst_QDom::setGetAttributes()
QVERIFY(bOk);
QCOMPARE(nsNode.attributeNS("namespace", "floatVal").toFloat(&bOk), floatVal);
QVERIFY(bOk);
- QCOMPARE(nsNode.attributeNS("namespace", "doubleVal").toDouble(&bOk), doubleVal);
- QVERIFY(bOk);
+ QVERIFY(nsNode.attributeNS("namespace", "doubleVal1").toDouble(&bOk) == doubleVal1 && bOk);
+ QVERIFY(nsNode.attributeNS("namespace", "doubleVal2").toDouble(&bOk) == doubleVal2 && bOk);
+ QVERIFY(nsNode.attributeNS("namespace", "doubleVal3").toDouble(&bOk) == doubleVal3 && bOk);
QLocale::setDefault(oldLocale);
}