/* This opens the specified library, mmaps it into memory, and searches for the QT_PLUGIN_VERIFICATION_DATA. The advantage of this approach is that we can get the verification data without have to actually load the library. This lets us detect mismatches more safely. Returns false if version/key information is not present, or if the information could not be read. Returns true if version/key information is present and successfully read. */ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QByteArray *key, QLibraryPrivate *lib = 0) { QFile file(library); if (!file.open(QIODevice::ReadOnly)) { if (lib) lib->errorString = file.errorString(); if (qt_debug_component()) { qWarning("%s: %s", (const char*) QFile::encodeName(library), qPrintable(qt_error_string(errno))); } return false; } QByteArray data; const char *filedata = 0; ulong fdlen = file.size(); filedata = (char *) file.map(0, fdlen); if (filedata == 0) { // try reading the data into memory instead data = file.readAll(); filedata = data.constData(); fdlen = data.size(); } /* ELF binaries on GNU, have .qplugin sections. */ long pos = 0; const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA"; const ulong plen = qstrlen(pattern); #if defined (Q_OF_ELF) && defined(Q_CC_GNU) int r = QElfParser().parse(filedata, fdlen, library, lib, &pos, &fdlen); if (r == QElfParser::NoQtSection) { if (pos > 0) { // find inside .rodata long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); if (rel < 0) { pos = -1; } else { pos += rel; } } else { pos = qt_find_pattern(filedata, fdlen, pattern, plen); } } else if (r != QElfParser::Ok) { if (lib && qt_debug_component()) { qWarning("QElfParser: %s",qPrintable(lib->errorString)); } return false; } #else pos = qt_find_pattern(filedata, fdlen, pattern, plen); #endif // defined(Q_OF_ELF) && defined(Q_CC_GNU) bool ret = false; if (pos >= 0) ret = qt_parse_pattern(filedata + pos, version, debug, key); if (!ret && lib) lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library); file.close(); return ret; }
/* This opens the specified library, mmaps it into memory, and searches for the QT_PLUGIN_VERIFICATION_DATA. The advantage of this approach is that we can get the verification data without have to actually load the library. This lets us detect mismatches more safely. Returns false if version information is not present, or if the information could not be read. Returns true if version information is present and successfully read. */ static bool qt_unix_query(const QString &library, QLibraryPrivate *lib) { QFile file(library); if (!file.open(QIODevice::ReadOnly)) { if (lib) lib->errorString = file.errorString(); if (qt_debug_component()) { qWarning("%s: %s", (const char*) QFile::encodeName(library), qPrintable(qt_error_string(errno))); } return false; } QByteArray data; const char *filedata = 0; ulong fdlen = file.size(); filedata = (char *) file.map(0, fdlen); if (filedata == 0) { // try reading the data into memory instead data = file.readAll(); filedata = data.constData(); fdlen = data.size(); } /* ELF binaries on GNU, have .qplugin sections. */ bool hasMetaData = false; long pos = 0; const char pattern[] = "QTMETADATA "; const ulong plen = qstrlen(pattern); #if defined (Q_OF_ELF) && defined(Q_CC_GNU) int r = QElfParser().parse(filedata, fdlen, library, lib, &pos, &fdlen); if (r == QElfParser::Corrupt || r == QElfParser::NotElf) { if (lib && qt_debug_component()) { qWarning("QElfParser: %s",qPrintable(lib->errorString)); } return false; } else if (r == QElfParser::QtMetaDataSection) { long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); if (rel < 0) pos = -1; else pos += rel; hasMetaData = true; } #else pos = qt_find_pattern(filedata, fdlen, pattern, plen); if (pos > 0) hasMetaData = true; #endif // defined(Q_OF_ELF) && defined(Q_CC_GNU) bool ret = false; if (pos >= 0) { if (hasMetaData) { const char *data = filedata + pos; QJsonDocument doc = QLibraryPrivate::fromRawMetaData(data); lib->metaData = doc.object(); if (qt_debug_component()) qWarning("Found metadata in lib %s, metadata=\n%s\n", library.toLocal8Bit().constData(), doc.toJson().constData()); ret = !doc.isNull(); } } if (!ret && lib) lib->errorString = QLibrary::tr("Plugin verification data mismatch in '%1'").arg(library); file.close(); return ret; }