Allow passing absolute paths without file extension to QPluginLoader

Previously QPluginLoader("/foo/bar/plugin").fileName() would return an
empty string even if /foo/bar/plugin.so existed, now we correctly find
that file.

Change-Id: Ibf6ba329e92956de45f695be65773caacf14050a
Reviewed-by: David Faure <david.faure@kdab.com>
bb10
Alex Richardson 2015-01-20 22:15:44 +00:00 committed by David Faure
parent c8d64cbcc6
commit 3146dadb42
2 changed files with 32 additions and 9 deletions

View File

@ -273,6 +273,13 @@ bool QPluginLoader::isLoaded() const
#if defined(QT_SHARED)
static QString locatePlugin(const QString& fileName)
{
const bool isAbsolute = QDir::isAbsolutePath(fileName);
if (isAbsolute) {
QFileInfo fi(fileName);
if (fi.isFile()) {
return fi.canonicalFilePath();
}
}
QStringList prefixes = QLibraryPrivate::prefixes_sys();
prefixes.prepend(QString());
QStringList suffixes = QLibraryPrivate::suffixes_sys(QString());
@ -281,12 +288,18 @@ static QString locatePlugin(const QString& fileName)
// Split up "subdir/filename"
const int slash = fileName.lastIndexOf('/');
const QString baseName = fileName.mid(slash + 1);
const QString basePath = fileName.left(slash + 1); // keep the '/'
const QString basePath = isAbsolute ? QString() : fileName.left(slash + 1); // keep the '/'
const bool debug = qt_debug_component();
QStringList paths = QCoreApplication::libraryPaths();
paths.prepend(QStringLiteral("./")); // search in current dir first
QStringList paths;
if (isAbsolute) {
paths.append(fileName.left(slash)); // don't include the '/'
} else {
paths = QCoreApplication::libraryPaths();
paths.prepend(QStringLiteral(".")); // search in current dir first
}
foreach (const QString &path, paths) {
foreach (const QString &prefix, prefixes) {
foreach (const QString &suffix, suffixes) {
@ -337,12 +350,7 @@ void QPluginLoader::setFileName(const QString &fileName)
did_load = false;
}
QFileInfo fi(fileName);
QString fn;
if (fi.isAbsolute())
fn = fi.canonicalFilePath();
else
fn = locatePlugin(fileName);
const QString fn = locatePlugin(fileName);
d = QLibraryPrivate::findOrCreate(fn, QString(), lh);
if (!fn.isEmpty())

View File

@ -120,6 +120,7 @@ private slots:
void loadGarbage();
#endif
void relativePath();
void absolutePath();
void reloadPlugin();
void preloadedPlugin_data();
void preloadedPlugin();
@ -406,6 +407,20 @@ void tst_QPluginLoader::relativePath()
QVERIFY(loader.unload());
}
void tst_QPluginLoader::absolutePath()
{
// Windows binaries run from release and debug subdirs, so we can't rely on the current dir.
const QString binDir = QFINDTESTDATA("bin");
QVERIFY(!binDir.isEmpty());
QVERIFY(QDir::isAbsolutePath(binDir));
QPluginLoader loader(binDir + "/theplugin");
loader.load(); // not recommended, instance() should do the job.
PluginInterface *instance = qobject_cast<PluginInterface*>(loader.instance());
QVERIFY(instance);
QCOMPARE(instance->pluginName(), QLatin1String("Plugin ok"));
QVERIFY(loader.unload());
}
void tst_QPluginLoader::reloadPlugin()
{
QPluginLoader loader;