diff options
-rw-r--r-- | src/corelib/plugin/qelfparser_p.cpp | 2 | ||||
-rw-r--r-- | src/corelib/plugin/qelfparser_p.h | 2 | ||||
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 46 | ||||
-rw-r--r-- | src/corelib/plugin/qmachparser.cpp | 2 | ||||
-rw-r--r-- | src/corelib/plugin/qmachparser_p.h | 2 | ||||
-rw-r--r-- | tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp | 4 |
6 files changed, 26 insertions, 32 deletions
diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp index 7a42b0d023..62555b006d 100644 --- a/src/corelib/plugin/qelfparser_p.cpp +++ b/src/corelib/plugin/qelfparser_p.cpp @@ -63,7 +63,7 @@ const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *s return data; } -int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen) +int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, qsizetype *pos, qsizetype *sectionlen) { #if defined(QELFPARSER_DEBUG) qDebug() << "QElfParser::parse " << library; diff --git a/src/corelib/plugin/qelfparser_p.h b/src/corelib/plugin/qelfparser_p.h index 3e73c5d149..1d3578255f 100644 --- a/src/corelib/plugin/qelfparser_p.h +++ b/src/corelib/plugin/qelfparser_p.h @@ -96,7 +96,7 @@ public: } const char *parseSectionHeader(const char* s, ElfSectionHeader *sh); - int parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen); + int parse(const char *m_s, ulong fdlen, const QString &library, QLibraryPrivate *lib, qsizetype *pos, qsizetype *sectionlen); }; QT_END_NAMESPACE diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index a3b8be8911..31abeaffe4 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -1,7 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. -** Copyright (C) 2016 Intel Corporation. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -186,7 +186,7 @@ QT_BEGIN_NAMESPACE */ -static long qt_find_pattern(const char *s, ulong s_len, +static qsizetype qt_find_pattern(const char *s, qsizetype s_len, const char *pattern, ulong p_len) { /* @@ -201,8 +201,10 @@ static long qt_find_pattern(const char *s, ulong s_len, because we have to skip over all the debugging symbols first */ - if (! s || ! pattern || p_len > s_len) return -1; - ulong i, hs = 0, hp = 0, delta = s_len - p_len; + if (!s || !pattern || qsizetype(p_len) > s_len) + return -1; + + size_t i, hs = 0, hp = 0, delta = s_len - p_len; for (i = 0; i < p_len; ++i) { hs += s[delta + i]; @@ -211,7 +213,7 @@ static long qt_find_pattern(const char *s, ulong s_len, i = delta; for (;;) { if (hs == hp && qstrncmp(s + i, pattern, p_len) == 0) - return i; + return i; // can't overflow, by construction if (i == 0) break; --i; @@ -245,35 +247,27 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) return false; } + // Files can be bigger than the virtual memory size on 32-bit systems, so + // we limit to 512 MB there. For 64-bit, we allow up to 2^40 bytes. + constexpr qint64 MaxMemoryMapSize = + Q_INT64_C(1) << (sizeof(qsizetype) > 4 ? 40 : 29); + QByteArray data; - ulong fdlen = file.size(); + qsizetype fdlen = qMin(file.size(), MaxMemoryMapSize); const char *filedata = reinterpret_cast<char *>(file.map(0, fdlen)); if (filedata == 0) { - if (uchar *mapdata = file.map(0, 1)) { - file.unmap(mapdata); - // Mapping is supported, but failed for the entire file, likely due to OOM. - // Return false, as readAll() would cause a bad_alloc and terminate the process. - if (lib) - lib->errorString = QLibrary::tr("Out of memory while loading plugin '%1'.").arg(library); - if (qt_debug_component()) { - qWarning("%s: %s", QFile::encodeName(library).constData(), - qPrintable(QSystemError::stdString(ENOMEM))); - } - return false; - } else { - // Try reading the data into memory instead. - data = file.readAll(); - filedata = data.constData(); - fdlen = data.size(); - } + // Try reading the data into memory instead (up to 64 MB). + data = file.read(64 * 1024 * 1024); + filedata = data.constData(); + fdlen = data.size(); } /* ELF and Mach-O binaries with GCC have .qplugin sections. */ bool hasMetaData = false; - long pos = 0; + qsizetype pos = 0; char pattern[] = "qTMETADATA "; pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it. const ulong plen = qstrlen(pattern); @@ -285,7 +279,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) } return false; } else if (r == QElfParser::QtMetaDataSection) { - long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); + qsizetype rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); if (rel < 0) pos = -1; else @@ -305,7 +299,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) } // even if the metadata section was not found, the Mach-O parser will // at least return the boundaries of the right architecture - long rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); + qsizetype rel = qt_find_pattern(filedata + pos, fdlen, pattern, plen); if (rel < 0) pos = -1; else diff --git a/src/corelib/plugin/qmachparser.cpp b/src/corelib/plugin/qmachparser.cpp index f506a6a6b1..11670cafe9 100644 --- a/src/corelib/plugin/qmachparser.cpp +++ b/src/corelib/plugin/qmachparser.cpp @@ -89,7 +89,7 @@ static int ns(const QString &reason, const QString &library, QString *errorStrin return QMachOParser::NotSuitable; } -int QMachOParser::parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen) +int QMachOParser::parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, qsizetype *pos, qsizetype *sectionlen) { // The minimum size of a Mach-O binary we're interested in. // It must have a full Mach header, at least one segment and at least one diff --git a/src/corelib/plugin/qmachparser_p.h b/src/corelib/plugin/qmachparser_p.h index 3884c92797..290b68876f 100644 --- a/src/corelib/plugin/qmachparser_p.h +++ b/src/corelib/plugin/qmachparser_p.h @@ -67,7 +67,7 @@ class Q_AUTOTEST_EXPORT QMachOParser { public: enum { QtMetaDataSection, NoQtSection, NotSuitable }; - static int parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, long *pos, ulong *sectionlen); + static int parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString, qsizetype *pos, qsizetype *sectionlen); }; QT_END_NAMESPACE diff --git a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp index 499d276ef8..a496ed318b 100644 --- a/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/corelib/plugin/qpluginloader/tst_qpluginloader.cpp @@ -345,8 +345,8 @@ void tst_QPluginLoader::loadMachO() QVERIFY(f.open(QIODevice::ReadOnly)); QByteArray data = f.readAll(); - long pos; - ulong len; + qsizetype pos; + qsizetype len; QString errorString; int r = QMachOParser::parse(data.constData(), data.size(), f.fileName(), &errorString, &pos, &len); |