diff options
Diffstat (limited to 'src/corelib/plugin/qmachparser.cpp')
| -rw-r--r-- | src/corelib/plugin/qmachparser.cpp | 37 |
1 files changed, 18 insertions, 19 deletions
diff --git a/src/corelib/plugin/qmachparser.cpp b/src/corelib/plugin/qmachparser.cpp index db4453dffeb..ef989f2ac09 100644 --- a/src/corelib/plugin/qmachparser.cpp +++ b/src/corelib/plugin/qmachparser.cpp @@ -81,15 +81,14 @@ static const uint32_t my_magic = MH_MAGIC; #endif Q_DECL_COLD_FUNCTION -static QLibraryScanResult ns(const QString &reason, const QString &library, QString *errorString) +static QLibraryScanResult notfound(const QString &reason, QString *errorString) { - if (errorString) - *errorString = QLibrary::tr("'%1' is not a valid Mach-O binary (%2)") - .arg(library, reason.isEmpty() ? QLibrary::tr("file is corrupt") : reason); + *errorString = QLibrary::tr("'%1' is not a valid Mach-O binary (%2)") + .arg(*errorString, reason.isEmpty() ? QLibrary::tr("file is corrupt") : reason); return {}; } -QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QString &library, QString *errorString) +QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, QString *errorString) { // 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 @@ -100,7 +99,7 @@ QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QStr static const size_t MinFatHeaderSize = sizeof(fat_header) + 2 * sizeof(fat_arch); if (Q_UNLIKELY(fdlen < MinFileSize)) - return ns(QLibrary::tr("file too small"), library, errorString); + return notfound(QLibrary::tr("file too small"), errorString); // find out if this is a fat Mach-O binary first const my_mach_header *header = nullptr; @@ -109,12 +108,12 @@ QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QStr // find our architecture in the binary const fat_arch *arch = reinterpret_cast<const fat_arch *>(fat + 1); if (Q_UNLIKELY(fdlen < MinFatHeaderSize)) { - return ns(QLibrary::tr("file too small"), library, errorString); + return notfound(QLibrary::tr("file too small"), errorString); } int count = qFromBigEndian(fat->nfat_arch); if (Q_UNLIKELY(fdlen < sizeof(*fat) + sizeof(*arch) * count)) - return ns(QString(), library, errorString); + return notfound(QString(), errorString); for (int i = 0; i < count; ++i) { if (arch[i].cputype == qToBigEndian(my_cputype)) { @@ -123,7 +122,7 @@ QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QStr uint32_t offset = qFromBigEndian(arch[i].offset); if (Q_UNLIKELY(size > fdlen) || Q_UNLIKELY(offset > fdlen) || Q_UNLIKELY(size + offset > fdlen) || Q_UNLIKELY(size < MinFileSize)) - return ns(QString(), library, errorString); + return notfound(QString(), errorString); header = reinterpret_cast<const my_mach_header *>(m_s + offset); fdlen = size; @@ -131,19 +130,19 @@ QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QStr } } if (!header) - return ns(QLibrary::tr("no suitable architecture in fat binary"), library, errorString); + return notfound(QLibrary::tr("no suitable architecture in fat binary"), errorString); // check the magic again if (Q_UNLIKELY(header->magic != my_magic)) - return ns(QString(), library, errorString); + return notfound(QString(), errorString); } else { header = reinterpret_cast<const my_mach_header *>(m_s); fat = 0; // check magic if (header->magic != my_magic) - return ns(QLibrary::tr("invalid magic %1").arg(qFromBigEndian(header->magic), 8, 16, QLatin1Char('0')), - library, errorString); + return notfound(QLibrary::tr("invalid magic %1").arg(qFromBigEndian(header->magic), 8, 16, QLatin1Char('0')), + errorString); } // from this point on, everything is in host byte order @@ -152,13 +151,13 @@ QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QStr // ### should we check the CPU subtype? Maybe on ARM? if (header->cputype != my_cputype) { if (fat) - return ns(QString(), library, errorString); - return ns(QLibrary::tr("wrong architecture"), library, errorString); + return notfound(QString(), errorString); + return notfound(QLibrary::tr("wrong architecture"), errorString); } // check the file type if (Q_UNLIKELY(header->filetype != MH_BUNDLE && header->filetype != MH_DYLIB)) - return ns(QLibrary::tr("not a dynamic library"), library, errorString); + return notfound(QLibrary::tr("not a dynamic library"), errorString); // find the __TEXT segment, "qtmetadata" section const my_segment_command *seg = reinterpret_cast<const my_segment_command *>(header + 1); @@ -169,14 +168,14 @@ QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QStr // We're sure that the file size includes at least one load command // but we have to check anyway if we're past the first if (Q_UNLIKELY(fdlen < minsize + sizeof(load_command))) - return ns(QString(), library, errorString); + return notfound(QString(), errorString); // cmdsize can't be trusted until validated // so check it against fdlen anyway // (these are unsigned operations, with overflow behavior specified in the standard) minsize += seg->cmdsize; if (Q_UNLIKELY(fdlen < minsize) || Q_UNLIKELY(fdlen < seg->cmdsize)) - return ns(QString(), library, errorString); + return notfound(QString(), errorString); const uint32_t MyLoadCommand = sizeof(void *) > 4 ? LC_SEGMENT_64 : LC_SEGMENT; if (seg->cmd != MyLoadCommand) @@ -193,7 +192,7 @@ QLibraryScanResult QMachOParser::parse(const char *m_s, ulong fdlen, const QStr // found it! if (Q_UNLIKELY(fdlen < sect[j].offset) || Q_UNLIKELY(fdlen < sect[j].size) || Q_UNLIKELY(fdlen < sect[j].offset + sect[j].size)) - return ns(QString(), library, errorString); + return notfound(QString(), errorString); qsizetype pos = reinterpret_cast<const char *>(header) - m_s + sect[j].offset; return { pos, qsizetype(sect[j].size) }; |
