mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-07 09:45:25 +08:00
qt 6.5.1 original
This commit is contained in:
42
tests/auto/corelib/plugin/qplugin/CMakeLists.txt
Normal file
42
tests/auto/corelib/plugin/qplugin/CMakeLists.txt
Normal file
@ -0,0 +1,42 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
add_subdirectory(invalidplugin)
|
||||
add_subdirectory(debugplugin)
|
||||
add_subdirectory(releaseplugin)
|
||||
|
||||
qt_internal_add_test(tst_qplugin
|
||||
SOURCES
|
||||
tst_qplugin.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
)
|
||||
|
||||
if(NOT ANDROID)
|
||||
# Collect test data
|
||||
file(GLOB_RECURSE test_data_glob
|
||||
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
plugins/*)
|
||||
list(APPEND test_data ${test_data_glob})
|
||||
set_target_properties(tst_qplugin PROPERTIES TESTDATA "${test_data}")
|
||||
else()
|
||||
# On Android the plugins must be located in the libs subdir of the APK.
|
||||
# Use QT_ANDROID_EXTRA_LIBS to achieve that.
|
||||
set(plugins
|
||||
invalidplugin
|
||||
debugplugin
|
||||
releaseplugin
|
||||
)
|
||||
set(extra_libs)
|
||||
foreach(plugin IN LISTS plugins)
|
||||
list(APPEND extra_libs
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/plugins/lib${plugin}_${CMAKE_ANDROID_ARCH_ABI}.so")
|
||||
endforeach()
|
||||
set_target_properties(tst_qplugin PROPERTIES
|
||||
QT_ANDROID_EXTRA_LIBS "${extra_libs}"
|
||||
)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(tst_qplugin PRIVATE CMAKE_BUILD=1)
|
||||
|
||||
add_dependencies(tst_qplugin invalidplugin debugplugin releaseplugin)
|
17
tests/auto/corelib/plugin/qplugin/debugplugin/CMakeLists.txt
Normal file
17
tests/auto/corelib/plugin/qplugin/debugplugin/CMakeLists.txt
Normal file
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## debugplugin Generic Library:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_cmake_library(debugplugin
|
||||
MODULE
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../plugins"
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
)
|
||||
|
||||
qt_autogen_tools_initial_setup(debugplugin)
|
14
tests/auto/corelib/plugin/qplugin/debugplugin/main.cpp
Normal file
14
tests/auto/corelib/plugin/qplugin/debugplugin/main.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QtPlugin>
|
||||
#include <QObject>
|
||||
|
||||
class DebugPlugin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "SomeIID")
|
||||
public:
|
||||
DebugPlugin() {}
|
||||
};
|
||||
|
||||
#include "main.moc"
|
@ -0,0 +1,19 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## invalidplugin Generic Library:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_cmake_library(invalidplugin
|
||||
MODULE
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../plugins"
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
)
|
||||
|
||||
# TEMPLATE = "lib"
|
||||
|
||||
qt_autogen_tools_initial_setup(invalidplugin)
|
25
tests/auto/corelib/plugin/qplugin/invalidplugin/main.cpp
Normal file
25
tests/auto/corelib/plugin/qplugin/invalidplugin/main.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright (C) 2018 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <qplugin.h>
|
||||
|
||||
// be careful when updating to V2, the header is different on ELF systems
|
||||
QT_PLUGIN_METADATA_SECTION
|
||||
static const char pluginMetaData[512] = {
|
||||
'q', 'p', 'l', 'u', 'g', 'i', 'n', ' ',
|
||||
't', 'e', 's', 't', 'f', 'i', 'l', 'e'
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
const void *qt_plugin_query_metadata()
|
||||
{
|
||||
return pluginMetaData;
|
||||
}
|
||||
|
||||
Q_DECL_EXPORT void *qt_plugin_instance()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## releaseplugin Generic Library:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_cmake_library(releaseplugin
|
||||
MODULE
|
||||
OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/../plugins"
|
||||
SOURCES
|
||||
main.cpp
|
||||
LIBRARIES
|
||||
Qt::Core
|
||||
)
|
||||
|
||||
qt_autogen_tools_initial_setup(releaseplugin)
|
14
tests/auto/corelib/plugin/qplugin/releaseplugin/main.cpp
Normal file
14
tests/auto/corelib/plugin/qplugin/releaseplugin/main.cpp
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QtPlugin>
|
||||
#include <QObject>
|
||||
|
||||
class ReleasePlugin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "SomeIID")
|
||||
public:
|
||||
ReleasePlugin() {}
|
||||
};
|
||||
|
||||
#include "main.moc"
|
238
tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
Normal file
238
tests/auto/corelib/plugin/qplugin/tst_qplugin.cpp
Normal file
@ -0,0 +1,238 @@
|
||||
// Copyright (C) 2020 The Qt Company Ltd.
|
||||
// Copyright (C) 2021 Intel Corporation.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
#include <QTest>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <qplugin.h>
|
||||
#include <QPluginLoader>
|
||||
|
||||
#include <private/qplugin_p.h>
|
||||
|
||||
class tst_QPlugin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
QDir dir;
|
||||
|
||||
public:
|
||||
tst_QPlugin();
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
void loadDebugPlugin();
|
||||
void loadReleasePlugin();
|
||||
void scanInvalidPlugin_data();
|
||||
void scanInvalidPlugin();
|
||||
};
|
||||
|
||||
tst_QPlugin::tst_QPlugin()
|
||||
{
|
||||
// On Android the plugins must be located in the APK's libs subdir
|
||||
#ifndef Q_OS_ANDROID
|
||||
dir = QFINDTESTDATA("plugins");
|
||||
#else
|
||||
const QStringList paths = QCoreApplication::libraryPaths();
|
||||
if (!paths.isEmpty())
|
||||
dir = paths.first();
|
||||
#endif
|
||||
}
|
||||
|
||||
void tst_QPlugin::initTestCase()
|
||||
{
|
||||
QVERIFY2(dir.exists(),
|
||||
qPrintable(QString::fromLatin1("Cannot find the 'plugins' directory starting from '%1'").
|
||||
arg(QDir::toNativeSeparators(QDir::currentPath()))));
|
||||
}
|
||||
|
||||
void tst_QPlugin::loadDebugPlugin()
|
||||
{
|
||||
const auto fileNames = dir.entryList(QStringList() << "*debug*", QDir::Files);
|
||||
if (fileNames.isEmpty())
|
||||
QSKIP("No debug plugins found - skipping test");
|
||||
|
||||
for (const QString &fileName : fileNames) {
|
||||
if (!QLibrary::isLibrary(fileName))
|
||||
continue;
|
||||
QPluginLoader loader(dir.filePath(fileName));
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
|
||||
// we can always load a plugin on unix
|
||||
QVERIFY(loader.load());
|
||||
QObject *object = loader.instance();
|
||||
QVERIFY(object != 0);
|
||||
#else
|
||||
# if defined(CMAKE_BUILD) && defined(QT_NO_DEBUG)
|
||||
QSKIP("Skipping test as it is not possible to disable build targets based on configuration with CMake");
|
||||
# endif
|
||||
// loading a plugin is dependent on which lib we are running against
|
||||
# if defined(QT_NO_DEBUG)
|
||||
// release build, we cannot load debug plugins
|
||||
QVERIFY(!loader.load());
|
||||
# else
|
||||
// debug build, we can load debug plugins
|
||||
QVERIFY(loader.load());
|
||||
QObject *object = loader.instance();
|
||||
QVERIFY(object != 0);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QPlugin::loadReleasePlugin()
|
||||
{
|
||||
const auto fileNames = dir.entryList(QStringList() << "*release*", QDir::Files);
|
||||
if (fileNames.isEmpty())
|
||||
QSKIP("No release plugins found - skipping test");
|
||||
|
||||
for (const QString &fileName : fileNames) {
|
||||
if (!QLibrary::isLibrary(fileName))
|
||||
continue;
|
||||
QPluginLoader loader(dir.filePath(fileName));
|
||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_MAC)
|
||||
// we can always load a plugin on unix
|
||||
QVERIFY(loader.load());
|
||||
QObject *object = loader.instance();
|
||||
QVERIFY(object != 0);
|
||||
#else
|
||||
# if defined(CMAKE_BUILD) && !defined(QT_NO_DEBUG)
|
||||
QSKIP("Skipping test as it is not possible to disable build targets based on configuration with CMake");
|
||||
# endif
|
||||
// loading a plugin is dependent on which lib we are running against
|
||||
# if defined(QT_NO_DEBUG)
|
||||
// release build, we can load debug plugins
|
||||
QVERIFY(loader.load());
|
||||
QObject *object = loader.instance();
|
||||
QVERIFY(object != 0);
|
||||
# else
|
||||
// debug build, we cannot load debug plugins
|
||||
QVERIFY(!loader.load());
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QPlugin::scanInvalidPlugin_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("metadata");
|
||||
QTest::addColumn<bool>("loads");
|
||||
QTest::addColumn<QString>("errMsg");
|
||||
|
||||
// CBOR metadata
|
||||
static constexpr QPluginMetaData::MagicHeader header = {};
|
||||
static constexpr qsizetype MagicLen = sizeof(header.magic);
|
||||
QByteArray cprefix(reinterpret_cast<const char *>(&header), sizeof(header));
|
||||
|
||||
QByteArray cborValid = [] {
|
||||
QCborMap m;
|
||||
m.insert(int(QtPluginMetaDataKeys::IID), QLatin1String("org.qt-project.tst_qplugin"));
|
||||
m.insert(int(QtPluginMetaDataKeys::ClassName), QLatin1String("tst"));
|
||||
m.insert(int(QtPluginMetaDataKeys::MetaData), QCborMap());
|
||||
return QCborValue(m).toCbor();
|
||||
}();
|
||||
QTest::newRow("cbor-control") << (cprefix + cborValid) << true << "";
|
||||
|
||||
cprefix[MagicLen + 1] = QT_VERSION_MAJOR + 1;
|
||||
QTest::newRow("cbor-major-too-new") << (cprefix + cborValid) << false << "";
|
||||
|
||||
cprefix[MagicLen + 1] = QT_VERSION_MAJOR - 1;
|
||||
QTest::newRow("cbor-major-too-old") << (cprefix + cborValid) << false << "";
|
||||
|
||||
cprefix[MagicLen + 1] = QT_VERSION_MAJOR;
|
||||
cprefix[MagicLen + 2] = QT_VERSION_MINOR + 1;
|
||||
QTest::newRow("cbor-minor-too-new") << (cprefix + cborValid) << false << "";
|
||||
|
||||
cprefix[MagicLen + 2] = QT_VERSION_MINOR;
|
||||
QTest::newRow("cbor-invalid") << (cprefix + "\xff") << false
|
||||
<< " Metadata parsing error: Invalid CBOR stream: unexpected 'break' byte";
|
||||
QTest::newRow("cbor-not-map1") << (cprefix + "\x01") << false
|
||||
<< " Unexpected metadata contents";
|
||||
QTest::newRow("cbor-not-map2") << (cprefix + "\x81\x01") << false
|
||||
<< " Unexpected metadata contents";
|
||||
|
||||
++cprefix[MagicLen + 0];
|
||||
QTest::newRow("cbor-major-too-new-invalid")
|
||||
<< (cprefix + cborValid) << false << " Invalid metadata version";
|
||||
}
|
||||
|
||||
static const char invalidPluginSignature[] = "qplugin testfile";
|
||||
static qsizetype locateMetadata(const uchar *data, qsizetype len)
|
||||
{
|
||||
const uchar *dataend = data + len - strlen(invalidPluginSignature);
|
||||
|
||||
for (const uchar *ptr = data; ptr < dataend; ++ptr) {
|
||||
if (*ptr != invalidPluginSignature[0])
|
||||
continue;
|
||||
|
||||
int r = memcmp(ptr, invalidPluginSignature, strlen(invalidPluginSignature));
|
||||
if (r)
|
||||
continue;
|
||||
|
||||
return ptr - data;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void tst_QPlugin::scanInvalidPlugin()
|
||||
{
|
||||
#if defined(Q_OS_MACOS) && defined(Q_PROCESSOR_ARM)
|
||||
QSKIP("This test crashes on ARM macOS");
|
||||
#endif
|
||||
const auto fileNames = dir.entryList({"*invalid*"}, QDir::Files);
|
||||
QString invalidPluginName;
|
||||
if (fileNames.isEmpty())
|
||||
QSKIP("No invalid plugin found - skipping test");
|
||||
else
|
||||
invalidPluginName = dir.absoluteFilePath(fileNames.first());
|
||||
|
||||
|
||||
// copy the file
|
||||
QFileInfo fn(invalidPluginName);
|
||||
QTemporaryDir tmpdir;
|
||||
QVERIFY(tmpdir.isValid());
|
||||
|
||||
QString newName = tmpdir.path() + '/' + fn.fileName();
|
||||
QVERIFY(QFile::copy(invalidPluginName, newName));
|
||||
|
||||
{
|
||||
QFile f(newName);
|
||||
QVERIFY(f.open(QIODevice::ReadWrite | QIODevice::Unbuffered));
|
||||
QVERIFY(f.size() > qint64(strlen(invalidPluginSignature)));
|
||||
uchar *data = f.map(0, f.size());
|
||||
QVERIFY(data);
|
||||
|
||||
static const qsizetype offset = locateMetadata(data, f.size());
|
||||
QVERIFY(offset > 0);
|
||||
|
||||
QFETCH(QByteArray, metadata);
|
||||
|
||||
// sanity check
|
||||
QVERIFY(metadata.size() < 512);
|
||||
|
||||
// replace the data
|
||||
memcpy(data + offset, metadata.constData(), metadata.size());
|
||||
memset(data + offset + metadata.size(), 0, 512 - metadata.size());
|
||||
}
|
||||
|
||||
#if defined(Q_OS_QNX)
|
||||
// On QNX plugin access is still too early
|
||||
QTest::qSleep(1000);
|
||||
#endif
|
||||
|
||||
// now try to load this
|
||||
QFETCH(bool, loads);
|
||||
QFETCH(QString, errMsg);
|
||||
if (!errMsg.isEmpty())
|
||||
QTest::ignoreMessage(QtWarningMsg,
|
||||
"Found invalid metadata in lib " + QFile::encodeName(newName) +
|
||||
":" + errMsg.toUtf8());
|
||||
QPluginLoader loader(newName);
|
||||
QCOMPARE(loader.load(), loads);
|
||||
if (loads)
|
||||
loader.unload();
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QPlugin)
|
||||
#include "tst_qplugin.moc"
|
Reference in New Issue
Block a user