From af1af7a14c7d89a34267d955ca75ddd7abf5a370 Mon Sep 17 00:00:00 2001 From: Nils Jeisecke Date: Tue, 31 Aug 2010 15:39:43 +0200 Subject: Implemented suffix and prefix strings for the numbering in ordered lists as supported by ODF. Works also with HTML import/export by using Qt CSS properties extensions. Merge-request: 1642 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qcssparser.cpp | 2 + src/gui/text/qcssparser_p.h | 2 + src/gui/text/qtextdocument.cpp | 34 ++++++++++++++-- src/gui/text/qtextdocumentfragment.cpp | 4 ++ src/gui/text/qtextformat.cpp | 38 ++++++++++++++++++ src/gui/text/qtextformat.h | 16 ++++++++ src/gui/text/qtexthtmlparser.cpp | 6 +++ src/gui/text/qtexthtmlparser_p.h | 2 + src/gui/text/qtextlist.cpp | 14 +++++-- src/gui/text/qtextodfwriter.cpp | 10 ++++- tests/auto/qtextlist/tst_qtextlist.cpp | 73 ++++++++++++++++++++++++++++++++++ 11 files changed, 193 insertions(+), 8 deletions(-) diff --git a/src/gui/text/qcssparser.cpp b/src/gui/text/qcssparser.cpp index 3fc6722..dafc8e7 100644 --- a/src/gui/text/qcssparser.cpp +++ b/src/gui/text/qcssparser.cpp @@ -68,6 +68,8 @@ static const QCssKnownValue properties[NumProperties - 1] = { { "-qt-background-role", QtBackgroundRole }, { "-qt-block-indent", QtBlockIndent }, { "-qt-list-indent", QtListIndent }, + { "-qt-list-number-prefix", QtListNumberPrefix }, + { "-qt-list-number-suffix", QtListNumberSuffix }, { "-qt-paragraph-type", QtParagraphType }, { "-qt-style-features", QtStyleFeatures }, { "-qt-table-type", QtTableType }, diff --git a/src/gui/text/qcssparser_p.h b/src/gui/text/qcssparser_p.h index 138d506..ca9688e 100644 --- a/src/gui/text/qcssparser_p.h +++ b/src/gui/text/qcssparser_p.h @@ -178,6 +178,8 @@ enum Property { OutlineBottomRightRadius, FontVariant, TextTransform, + QtListNumberPrefix, + QtListNumberSuffix, NumProperties }; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 42d6c66..887ac6c 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2591,14 +2591,40 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block) default: html += QLatin1String(""); } diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp index 7c5f973..d2e2c9f 100644 --- a/src/gui/text/qtextdocumentfragment.cpp +++ b/src/gui/text/qtextdocumentfragment.cpp @@ -683,6 +683,10 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processSpecialNodes() QTextListFormat listFmt; listFmt.setStyle(style); + if (!currentNode->textListNumberPrefix.isNull()) + listFmt.setNumberPrefix(currentNode->textListNumberPrefix); + if (!currentNode->textListNumberSuffix.isNull()) + listFmt.setNumberSuffix(currentNode->textListNumberSuffix); ++indent; if (currentNode->hasCssListIndent) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index e0a4096..ffa0ebc 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -2227,6 +2227,44 @@ QTextListFormat::QTextListFormat(const QTextFormat &fmt) \sa setIndent() */ +/*! + \fn void QTextListFormat::setNumberPrefix(const QString &numberPrefix) + \since 4.8 + + Sets the list format's number prefix. This can be used with all + sorted list types. It does not have any effect on unsorted list types. + + \sa numberPrefix() +*/ + +/*! + \fn int QTextListFormat::numberPrefix() const + \since 4.8 + + Returns the list format's number prefix. + + \sa setNumberPrefix() +*/ + +/*! + \fn void QTextListFormat::setNumberSuffix(const QString &numberSuffix) + \since 4.8 + + Sets the list format's number suffix. This can be used with all + sorted list types. It does not have any effect on unsorted list types. + The default suffix is ".". + + \sa numberSuffix() +*/ + +/*! + \fn int QTextListFormat::numberSuffix() const + \since 4.8 + + Returns the list format's number suffix. + + \sa setNumberSuffix() +*/ /*! \class QTextFrameFormat diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index ecf48a2..1de83bf 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -202,6 +202,8 @@ public: // list properties ListStyle = 0x3000, ListIndent = 0x3001, + ListNumberPrefix = 0x3002, + ListNumberSuffix = 0x3003, // table and frame properties FrameBorder = 0x4000, @@ -617,6 +619,14 @@ public: inline int indent() const { return intProperty(ListIndent); } + inline void setNumberPrefix(const QString &numberPrefix); + inline QString numberPrefix() const + { return stringProperty(ListNumberPrefix); } + + inline void setNumberSuffix(const QString &numberSuffix); + inline QString numberSuffix() const + { return stringProperty(ListNumberSuffix); } + protected: explicit QTextListFormat(const QTextFormat &fmt); friend class QTextFormat; @@ -628,6 +638,12 @@ inline void QTextListFormat::setStyle(Style astyle) inline void QTextListFormat::setIndent(int aindent) { setProperty(ListIndent, aindent); } +inline void QTextListFormat::setNumberPrefix(const QString &numberPrefix) +{ setProperty(ListNumberPrefix, numberPrefix); } + +inline void QTextListFormat::setNumberSuffix(const QString &numberSuffix) +{ setProperty(ListNumberSuffix, numberSuffix); } + class Q_GUI_EXPORT QTextImageFormat : public QTextCharFormat { public: diff --git a/src/gui/text/qtexthtmlparser.cpp b/src/gui/text/qtexthtmlparser.cpp index e190379..27f647c 100644 --- a/src/gui/text/qtexthtmlparser.cpp +++ b/src/gui/text/qtexthtmlparser.cpp @@ -1324,6 +1324,12 @@ void QTextHtmlParserNode::applyCssDeclarations(const QVector case QCss::ListStyle: setListStyle(decl.d->values); break; + case QCss::QtListNumberPrefix: + textListNumberPrefix = decl.d->values.first().variant.toString(); + break; + case QCss::QtListNumberSuffix: + textListNumberSuffix = decl.d->values.first().variant.toString(); + break; default: break; } } diff --git a/src/gui/text/qtexthtmlparser_p.h b/src/gui/text/qtexthtmlparser_p.h index 94cfa74..20188ab 100644 --- a/src/gui/text/qtexthtmlparser_p.h +++ b/src/gui/text/qtexthtmlparser_p.h @@ -180,6 +180,8 @@ struct QTextHtmlParserNode { uint displayMode : 3; // QTextHtmlElement::DisplayMode uint hasHref : 1; QTextListFormat::Style listStyle; + QString textListNumberPrefix; + QString textListNumberSuffix; QString imageName; qreal imageWidth; qreal imageHeight; diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index a0ff520..c312d89 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -191,6 +191,13 @@ QString QTextList::itemText(const QTextBlock &blockIt) const QString result; const int style = format().style(); + QString numberPrefix; + QString numberSuffix = QLatin1String("."); + + if (format().hasProperty(QTextFormat::ListNumberPrefix)) + numberPrefix = format().numberPrefix(); + if (format().hasProperty(QTextFormat::ListNumberSuffix)) + numberSuffix = format().numberSuffix(); switch (style) { case QTextListFormat::ListDecimal: @@ -232,7 +239,7 @@ QString QTextList::itemText(const QTextBlock &blockIt) const if (q > 0) { int startDigit = i + (i+3)/4; int numDigits; - if (i % 4) { + if (i % 4) { // c[i] == 4|5|9|40|50|90|400|500|900 if ((i-2) % 4) { // c[i] == 4|9|40|90|400|900 => with substraction (IV, IX, XL, XC, ...) @@ -263,8 +270,9 @@ QString QTextList::itemText(const QTextBlock &blockIt) const Q_ASSERT(false); } if (blockIt.textDirection() == Qt::RightToLeft) - return result.prepend(QLatin1Char('.')); - return result + QLatin1Char('.'); + return numberSuffix + result + numberPrefix; + else + return numberPrefix + result + numberSuffix; } /*! diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp index 7992de5..04f6913 100644 --- a/src/gui/text/qtextodfwriter.cpp +++ b/src/gui/text/qtextodfwriter.cpp @@ -636,7 +636,15 @@ void QTextOdfWriter::writeListFormat(QXmlStreamWriter &writer, QTextListFormat f || style == QTextListFormat::ListUpperRoman) { writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-number")); writer.writeAttribute(styleNS, QString::fromLatin1("num-format"), bulletChar(style)); - writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), QString::fromLatin1(".")); + + if (format.hasProperty(QTextFormat::ListNumberSuffix)) + writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), format.numberSuffix()); + else + writer.writeAttribute(styleNS, QString::fromLatin1("num-suffix"), QString::fromLatin1(".")); + + if (format.hasProperty(QTextFormat::ListNumberPrefix)) + writer.writeAttribute(styleNS, QString::fromLatin1("num-prefix"), format.numberPrefix()); + } else { writer.writeStartElement(textNS, QString::fromLatin1("list-level-style-bullet")); writer.writeAttribute(textNS, QString::fromLatin1("bullet-char"), bulletChar(style)); diff --git a/tests/auto/qtextlist/tst_qtextlist.cpp b/tests/auto/qtextlist/tst_qtextlist.cpp index 3e92836..8ad0898 100644 --- a/tests/auto/qtextlist/tst_qtextlist.cpp +++ b/tests/auto/qtextlist/tst_qtextlist.cpp @@ -67,6 +67,9 @@ private slots: void item(); void autoNumbering(); void autoNumberingRTL(); + void autoNumberingPrefixAndSuffix(); + void autoNumberingPrefixAndSuffixRTL(); + void autoNumberingPrefixAndSuffixHtmlExportImport(); void romanNumbering(); void romanNumberingLimit(); void formatChange(); @@ -128,6 +131,76 @@ void tst_QTextList::autoNumbering() QVERIFY(cursor.currentList()->itemText(cursor.block()) == "ab."); } +void tst_QTextList::autoNumberingPrefixAndSuffix() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerAlpha); + fmt.setNumberPrefix("-"); + fmt.setNumberSuffix(")"); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 27; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 28); + + QVERIFY(cursor.currentList()); + QVERIFY(cursor.currentList()->itemNumber(cursor.block()) == 27); + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "-ab)"); +} + +void tst_QTextList::autoNumberingPrefixAndSuffixRTL() +{ + QTextBlockFormat bfmt; + bfmt.setLayoutDirection(Qt::RightToLeft); + cursor.setBlockFormat(bfmt); + + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListUpperAlpha); + fmt.setNumberPrefix("-"); + fmt.setNumberSuffix("*"); + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + cursor.insertBlock(); + + QVERIFY(list->count() == 2); + + QVERIFY(cursor.currentList()->itemText(cursor.block()) == "*B-"); +} + +void tst_QTextList::autoNumberingPrefixAndSuffixHtmlExportImport() +{ + QTextListFormat fmt; + fmt.setStyle(QTextListFormat::ListLowerAlpha); + fmt.setNumberPrefix("\""); + fmt.setNumberSuffix("#"); + fmt.setIndent(10); + // FIXME: Would like to test "'" but there's a problem in the css parser (Scanner::preprocess + // is called before the values are being parsed), so the quoting does not work. + QTextList *list = cursor.createList(fmt); + QVERIFY(list); + + for (int i = 0; i < 27; ++i) + cursor.insertBlock(); + + QVERIFY(list->count() == 28); + + QString htmlExport = doc->toHtml(); + QTextDocument importDoc; + importDoc.setHtml(htmlExport); + + QTextCursor importCursor(&importDoc); + for (int i = 0; i < 27; ++i) + importCursor.movePosition(QTextCursor::NextBlock); + + QVERIFY(importCursor.currentList()); + QVERIFY(importCursor.currentList()->itemNumber(importCursor.block()) == 27); + QVERIFY(importCursor.currentList()->itemText(importCursor.block()) == "\"ab#"); + QVERIFY(importCursor.currentList()->format().indent() == 10); +} + void tst_QTextList::autoNumberingRTL() { QTextBlockFormat bfmt; -- cgit v0.12 From 805780554f7b7e22ae982198c978302463ad19b4 Mon Sep 17 00:00:00 2001 From: Jiang Jiang Date: Tue, 31 Aug 2010 15:57:16 +0200 Subject: Clean up and clarify Mac font engine code Reviewed-by: Eskil --- src/gui/text/qfontdatabase_mac.cpp | 75 +------------------------------------- src/gui/text/qfontengine_mac.mm | 1 + 2 files changed, 2 insertions(+), 74 deletions(-) diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp index 5a9fc35..4648304 100644 --- a/src/gui/text/qfontdatabase_mac.cpp +++ b/src/gui/text/qfontdatabase_mac.cpp @@ -334,89 +334,16 @@ FamilyFound: fontDef.pointSize = qt_mac_pointsize(fontDef, d->dpi); else fontDef.pixelSize = qt_mac_pixelsize(fontDef, d->dpi); -#if 0 - ItemCount name_count; - if(ATSUCountFontNames(fontID, &name_count) == noErr && name_count) { - ItemCount actualName_size; - if(ATSUGetIndFontName(fontID, 0, 0, 0, &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) { - QByteArray actualName(actualName_size); - if(ATSUGetIndFontName(fontID, 0, actualName_size, actualName.data(), &actualName_size, 0, 0, 0, 0) == noErr && actualName_size) - fontDef.family = QString::fromUtf8(actualName); - } - } -#else { QCFString actualName; if(ATSFontFamilyGetName(familyRef, kATSOptionFlagsDefault, &actualName) == noErr) fontDef.family = actualName; } -#endif #ifdef QT_MAC_USE_COCOA QFontEngine *engine = new QCoreTextFontEngineMulti(familyRef, fontRef, fontDef, d->kerning); -#elif 1 - QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning); #else - ATSFontFamilyRef atsFamily = familyRef; - ATSFontFamilyRef atsFontRef = fontRef; - - FMFont fontID; - FMFontFamily fmFamily; - FMFontStyle fntStyle = 0; - fmFamily = FMGetFontFamilyFromATSFontFamilyRef(atsFamily); - if (fmFamily == kInvalidFontFamily) { - // Use the ATSFont then... - fontID = FMGetFontFromATSFontRef(atsFontRef); - } else { - if (fontDef.weight >= QFont::Bold) - fntStyle |= ::bold; - if (fontDef.style != QFont::StyleNormal) - fntStyle |= ::italic; - - FMFontStyle intrinsicStyle; - FMFont fnt = 0; - if (FMGetFontFromFontFamilyInstance(fmFamily, fntStyle, &fnt, &intrinsicStyle) == noErr) - fontID = FMGetATSFontRefFromFont(fnt); - } - - OSStatus status; - - const int maxAttributeCount = 5; - ATSUAttributeTag tags[maxAttributeCount + 1]; - ByteCount sizes[maxAttributeCount + 1]; - ATSUAttributeValuePtr values[maxAttributeCount + 1]; - int attributeCount = 0; - - Fixed size = FixRatio(fontDef.pixelSize, 1); - tags[attributeCount] = kATSUSizeTag; - sizes[attributeCount] = sizeof(size); - values[attributeCount] = &size; - ++attributeCount; - - tags[attributeCount] = kATSUFontTag; - sizes[attributeCount] = sizeof(fontID); - values[attributeCount] = &fontID; - ++attributeCount; - - CGAffineTransform transform = CGAffineTransformIdentity; - if (fontDef.stretch != 100) { - transform = CGAffineTransformMakeScale(float(fontDef.stretch) / float(100), 1); - tags[attributeCount] = kATSUFontMatrixTag; - sizes[attributeCount] = sizeof(transform); - values[attributeCount] = &transform; - ++attributeCount; - } - - ATSUStyle style; - status = ATSUCreateStyle(&style); - Q_ASSERT(status == noErr); - - Q_ASSERT(attributeCount < maxAttributeCount + 1); - status = ATSUSetAttributes(style, attributeCount, tags, sizes, values); - Q_ASSERT(status == noErr); - - QFontEngine *engine = new QFontEngineMac(style, fontID, fontDef, /*multiEngine*/ 0); - ATSUDisposeStyle(style); + QFontEngine *engine = new QFontEngineMacMulti(familyRef, fontRef, fontDef, d->kerning); #endif d->engineData->engine = engine; engine->ref.ref(); //a ref for the engineData->engine diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 011cfe3..2bbf9f2 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -1426,6 +1426,7 @@ static inline unsigned int getChar(const QChar *str, int &i, const int len) return uc; } +// Not used directly for shaping, only used to calculate m_averageCharWidth bool QFontEngineMac::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const { if (!cmap) { -- cgit v0.12 From 2e6ad2872890c2cd7f305b2a11acbef9f446eb3e Mon Sep 17 00:00:00 2001 From: Arvid Ephraim Picciani Date: Tue, 31 Aug 2010 08:32:48 +0000 Subject: Add gdb-index section to debug binaries. Speeds up debugging on platforms with recent gdb. Task-number: QTCREATORBUG-2215 Reviewed-by: ossi --- mkspecs/features/unix/gdb_dwarf_index.prf | 13 +++++++++++++ mkspecs/freebsd-g++/qmake.conf | 2 +- mkspecs/freebsd-g++40/qmake.conf | 2 +- mkspecs/linux-g++-32/qmake.conf | 2 +- mkspecs/linux-g++-64/qmake.conf | 2 +- mkspecs/linux-g++-maemo/qmake.conf | 2 +- mkspecs/linux-g++/qmake.conf | 2 +- mkspecs/linux-icc/qmake.conf | 2 +- mkspecs/linux-llvm/qmake.conf | 2 +- mkspecs/linux-lsb-g++/qmake.conf | 2 +- mkspecs/netbsd-g++/qmake.conf | 2 +- mkspecs/openbsd-g++/qmake.conf | 2 +- 12 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 mkspecs/features/unix/gdb_dwarf_index.prf diff --git a/mkspecs/features/unix/gdb_dwarf_index.prf b/mkspecs/features/unix/gdb_dwarf_index.prf new file mode 100644 index 0000000..7824d93 --- /dev/null +++ b/mkspecs/features/unix/gdb_dwarf_index.prf @@ -0,0 +1,13 @@ +!CONFIG(separate_debug_info):CONFIG(debug, debug|release):!staticlib:!static:!contains(TEMPLATE, subdirs):!isEmpty(QMAKE_OBJCOPY) { + + QMAKE_GDB_INDEX = test -z \"$(DESTDIR)\" || cd \"$(DESTDIR)\" ; \ + gdb -silent -ex \'set confirm off\' -ex \'save gdb-index .\' -ex quit \'$(TARGET)\' >/dev/null 2>&1 && \ + test -f $(TARGET).gdb-index && \ + $$QMAKE_OBJCOPY --add-section \'.gdb_index=$(TARGET).gdb-index\' --set-section-flags \'.gdb_index=readonly\' \'$(TARGET)\' \'$(TARGET)\' || true + + !isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK + QMAKE_POST_LINK = $$QMAKE_GDB_INDEX $$QMAKE_POST_LINK + + silent:QMAKE_POST_LINK = @echo indexing $@ for gdb && $$QMAKE_POST_LINK +} + diff --git a/mkspecs/freebsd-g++/qmake.conf b/mkspecs/freebsd-g++/qmake.conf index ac52e0f..9de93d4 100644 --- a/mkspecs/freebsd-g++/qmake.conf +++ b/mkspecs/freebsd-g++/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release link_prl +CONFIG += qt warn_on release link_prl gdb_dwarf_index QT += core gui QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE diff --git a/mkspecs/freebsd-g++40/qmake.conf b/mkspecs/freebsd-g++40/qmake.conf index 3d0851a..bf42711 100644 --- a/mkspecs/freebsd-g++40/qmake.conf +++ b/mkspecs/freebsd-g++40/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release link_prl +CONFIG += qt warn_on release link_prl gdb_dwarf_index QT += core gui QMAKE_CC = gcc40 diff --git a/mkspecs/linux-g++-32/qmake.conf b/mkspecs/linux-g++-32/qmake.conf index 1e5c50b..f425c0d 100644 --- a/mkspecs/linux-g++-32/qmake.conf +++ b/mkspecs/linux-g++-32/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/linux-g++-64/qmake.conf b/mkspecs/linux-g++-64/qmake.conf index e7372cc..b8877a9 100644 --- a/mkspecs/linux-g++-64/qmake.conf +++ b/mkspecs/linux-g++-64/qmake.conf @@ -8,7 +8,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/linux-g++-maemo/qmake.conf b/mkspecs/linux-g++-maemo/qmake.conf index a977e7a..8f85c54 100644 --- a/mkspecs/linux-g++-maemo/qmake.conf +++ b/mkspecs/linux-g++-maemo/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index CONFIG += nostrip QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/linux-g++/qmake.conf b/mkspecs/linux-g++/qmake.conf index 4b21896..d772b5e 100644 --- a/mkspecs/linux-g++/qmake.conf +++ b/mkspecs/linux-g++/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf index 16e5197..f40a465 100644 --- a/mkspecs/linux-icc/qmake.conf +++ b/mkspecs/linux-icc/qmake.conf @@ -13,7 +13,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release link_prl +CONFIG += qt warn_on release link_prl gdb_dwarf_index QT += core gui QMAKE_CC = icc diff --git a/mkspecs/linux-llvm/qmake.conf b/mkspecs/linux-llvm/qmake.conf index 73d6609..77f8d81 100644 --- a/mkspecs/linux-llvm/qmake.conf +++ b/mkspecs/linux-llvm/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/linux-lsb-g++/qmake.conf b/mkspecs/linux-lsb-g++/qmake.conf index d359625..4197db0 100644 --- a/mkspecs/linux-lsb-g++/qmake.conf +++ b/mkspecs/linux-lsb-g++/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release incremental link_prl +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index QT += core gui QMAKE_INCREMENTAL_STYLE = sublib diff --git a/mkspecs/netbsd-g++/qmake.conf b/mkspecs/netbsd-g++/qmake.conf index 4d4270d..ab4b7c3 100644 --- a/mkspecs/netbsd-g++/qmake.conf +++ b/mkspecs/netbsd-g++/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release link_prl +CONFIG += qt warn_on release link_prl gdb_dwarf_index QT += core gui QMAKE_CC = gcc diff --git a/mkspecs/openbsd-g++/qmake.conf b/mkspecs/openbsd-g++/qmake.conf index f4bb223..56d9416 100644 --- a/mkspecs/openbsd-g++/qmake.conf +++ b/mkspecs/openbsd-g++/qmake.conf @@ -5,7 +5,7 @@ MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app -CONFIG += qt warn_on release link_prl +CONFIG += qt warn_on release link_prl gdb_dwarf_index QT += core gui QMAKE_CC = gcc -- cgit v0.12 From f6e8ff07243b693dfc45bdeb4882e4f52f90930a Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 1 Sep 2010 09:46:18 +0200 Subject: Fix compiler warning in qtextformat.h When compiling with -Wshadow, function arguments that shadow a class member generate a warning. Change the name in the implementation of the new functions to avoid this warning. Reviewed-by: Samuel --- src/gui/text/qtextformat.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index 1de83bf..bb6e71d 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -638,11 +638,11 @@ inline void QTextListFormat::setStyle(Style astyle) inline void QTextListFormat::setIndent(int aindent) { setProperty(ListIndent, aindent); } -inline void QTextListFormat::setNumberPrefix(const QString &numberPrefix) -{ setProperty(ListNumberPrefix, numberPrefix); } +inline void QTextListFormat::setNumberPrefix(const QString &np) +{ setProperty(ListNumberPrefix, np); } -inline void QTextListFormat::setNumberSuffix(const QString &numberSuffix) -{ setProperty(ListNumberSuffix, numberSuffix); } +inline void QTextListFormat::setNumberSuffix(const QString &ns) +{ setProperty(ListNumberSuffix, ns); } class Q_GUI_EXPORT QTextImageFormat : public QTextCharFormat { -- cgit v0.12 From b80e006058d3b73db8a583981e471c334f0e6b93 Mon Sep 17 00:00:00 2001 From: Arvid Ephraim Picciani Date: Wed, 1 Sep 2010 11:30:20 +0200 Subject: Optimize plugin loading on ELF platforms This is equal to 3c2a43f91e0225bde8d6e6d6076dfe2cddbc2f8e except the alignment checks have been relaxed. Reviewed-by: janarve --- src/corelib/plugin/plugin.pri | 6 +- src/corelib/plugin/qelfparser_p.cpp | 234 +++++++++++++++++++++ src/corelib/plugin/qelfparser_p.h | 103 +++++++++ src/corelib/plugin/qlibrary.cpp | 28 ++- tests/auto/qpluginloader/elftest/.gitattributes | 10 + tests/auto/qpluginloader/elftest/corrupt1.elf64.so | Bin 0 -> 239745 bytes tests/auto/qpluginloader/elftest/corrupt2.elf64.so | Bin 0 -> 240097 bytes tests/auto/qpluginloader/elftest/corrupt3.elf64.so | Bin 0 -> 240097 bytes tests/auto/qpluginloader/elftest/debugobj.so | Bin 0 -> 507232 bytes tests/auto/qpluginloader/elftest/garbage1.so | 4 + tests/auto/qpluginloader/elftest/garbage2.so | 1 + tests/auto/qpluginloader/elftest/garbage3.so | 1 + tests/auto/qpluginloader/elftest/garbage4.so | 1 + tests/auto/qpluginloader/elftest/garbage5.so | 2 + tests/auto/qpluginloader/tst_qpluginloader.cpp | 52 +++++ 15 files changed, 436 insertions(+), 6 deletions(-) create mode 100644 src/corelib/plugin/qelfparser_p.cpp create mode 100644 src/corelib/plugin/qelfparser_p.h create mode 100644 tests/auto/qpluginloader/elftest/.gitattributes create mode 100755 tests/auto/qpluginloader/elftest/corrupt1.elf64.so create mode 100755 tests/auto/qpluginloader/elftest/corrupt2.elf64.so create mode 100755 tests/auto/qpluginloader/elftest/corrupt3.elf64.so create mode 100644 tests/auto/qpluginloader/elftest/debugobj.so create mode 100644 tests/auto/qpluginloader/elftest/garbage1.so create mode 100644 tests/auto/qpluginloader/elftest/garbage2.so create mode 100644 tests/auto/qpluginloader/elftest/garbage3.so create mode 100644 tests/auto/qpluginloader/elftest/garbage4.so create mode 100644 tests/auto/qpluginloader/elftest/garbage5.so diff --git a/src/corelib/plugin/plugin.pri b/src/corelib/plugin/plugin.pri index 2e986ec..2e7db5d 100644 --- a/src/corelib/plugin/plugin.pri +++ b/src/corelib/plugin/plugin.pri @@ -7,13 +7,15 @@ HEADERS += \ plugin/qlibrary_p.h \ plugin/qplugin.h \ plugin/quuid.h \ - plugin/qfactoryloader_p.h + plugin/qfactoryloader_p.h \ + plugin/qelfparser_p.h SOURCES += \ plugin/qpluginloader.cpp \ plugin/qfactoryloader.cpp \ plugin/quuid.cpp \ - plugin/qlibrary.cpp + plugin/qlibrary.cpp \ + plugin/qelfparser_p.cpp win32 { SOURCES += plugin/qlibrary_win.cpp diff --git a/src/corelib/plugin/qelfparser_p.cpp b/src/corelib/plugin/qelfparser_p.cpp new file mode 100644 index 0000000..2e77ae7 --- /dev/null +++ b/src/corelib/plugin/qelfparser_p.cpp @@ -0,0 +1,234 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qlibrary_p.h" +#include "qelfparser_p.h" +#include + +QT_BEGIN_NAMESPACE + +// #define QELFPARSER_DEBUG 1 + +const char *QElfParser::parseSectionHeader(const char *data, ElfSectionHeader *sh) +{ + sh->name = read(data); + data += sizeof(qelfword_t); // sh_name + sh->type = read(data); + data += sizeof(qelfword_t) // sh_type + + sizeof(qelfaddr_t) // sh_flags + + sizeof(qelfaddr_t); // sh_addr + sh->offset = read(data); + data += sizeof(qelfoff_t); // sh_offset + sh->size = read(data); + data += sizeof(qelfword_t); // sh_size + return data; +} + +int QElfParser::parse(const char *dataStart, ulong fdlen, const QString &library, QLibraryPrivate *lib, long *pos, ulong *sectionlen) +{ +#if defined(QELFPARSER_DEBUG) + qDebug() << "QElfParser::parse " << library; +#endif + + if (fdlen < 64){ + if (lib) + lib->errorString = QLibrary::tr("'%1' is not an ELF object (%2)").arg(library).arg(QLatin1String("file too small")); + return NotElf; + } + const char *data = dataStart; + if (qstrncmp(data, "\177ELF", 4) != 0) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is not an ELF object").arg(library); + return NotElf; + } + // 32 or 64 bit + if (data[4] != 1 && data[4] != 2) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd cpu architecture")); + return Corrupt; + } + m_bits = (data[4] << 5); + + /* If you remove this check, to read ELF objects of a different arch, please make sure you modify the typedefs + to match the _plugin_ architecture. + */ + if ((sizeof(void*) == 4 && m_bits != 32) || (sizeof(void*) == 8 && m_bits != 64)) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("wrong cpu architecture")); + return Corrupt; + } + // endian + if (data[5] == 0) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("odd endianess")); + return Corrupt; + } + m_endian = (data[5] == 1 ? ElfLittleEndian : ElfBigEndian); + + data += 16 // e_ident + + sizeof(qelfhalf_t) // e_type + + sizeof(qelfhalf_t) // e_machine + + sizeof(qelfword_t) // e_version + + sizeof(qelfaddr_t) // e_entry + + sizeof(qelfoff_t); // e_phoff + + qelfoff_t e_shoff = read (data); + data += sizeof(qelfoff_t) // e_shoff + + sizeof(qelfword_t); // e_flags + + qelfhalf_t e_shsize = read (data); + + if (e_shsize > fdlen) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shsize")); + return Corrupt; + } + + data += sizeof(qelfhalf_t) // e_ehsize + + sizeof(qelfhalf_t) // e_phentsize + + sizeof(qelfhalf_t); // e_phnum + + qelfhalf_t e_shentsize = read (data); + + if (e_shentsize % 4){ + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library).arg(QLatin1String("unexpected e_shentsize")); + return Corrupt; + } + data += sizeof(qelfhalf_t); // e_shentsize + qelfhalf_t e_shnum = read (data); + data += sizeof(qelfhalf_t); // e_shnum + qelfhalf_t e_shtrndx = read (data); + data += sizeof(qelfhalf_t); // e_shtrndx + + if ((e_shnum * e_shentsize) > fdlen) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) + .arg(QLatin1String("announced %2 sections, each %3 bytes, exceed file size")) + .arg(e_shnum).arg(e_shentsize); + return Corrupt; + } + +#if defined(QELFPARSER_DEBUG) + qDebug() << e_shnum << "sections starting at " << ("0x" + QByteArray::number(e_shoff, 16)).data() << "each" << e_shentsize << "bytes"; +#endif + + ElfSectionHeader strtab; + qulonglong soff = e_shoff + e_shentsize * (e_shtrndx); + + if ((soff + e_shentsize) > fdlen || soff % 4 || soff == 0) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) + .arg(QLatin1String("shstrtab section header seems to be at %1")) + .arg(QString::number(soff, 16)); + return Corrupt; + } + + parseSectionHeader(dataStart + soff, &strtab); + m_stringTableFileOffset = strtab.offset; + + if ((m_stringTableFileOffset + e_shentsize) >= fdlen || m_stringTableFileOffset == 0) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) + .arg(QLatin1String("string table seems to be at %1")) + .arg(QString::number(soff, 16)); + return Corrupt; + } + +#if defined(QELFPARSER_DEBUG) + qDebug(".shstrtab at 0x%s", QByteArray::number(m_stringTableFileOffset, 16).data()); +#endif + + const char *s = dataStart + e_shoff; + for (int i = 0; i < e_shnum; ++i) { + ElfSectionHeader sh; + parseSectionHeader(s, &sh); + if (sh.name == 0) { + s += e_shentsize; + continue; + } + const char *shnam = dataStart + m_stringTableFileOffset + sh.name; + + if (m_stringTableFileOffset + sh.name > fdlen) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) + .arg(QLatin1String("section name %2 of %3 behind end of file")) + .arg(i).arg(e_shnum); + return Corrupt; + } + +#if defined(QELFPARSER_DEBUG) + qDebug() << "++++" << i << shnam; +#endif + + if (qstrcmp(shnam, ".qtplugin") == 0 || qstrcmp(shnam, ".rodata") == 0) { + if (!(sh.type & 0x1)) { + if (shnam[1] == 'r') { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) + .arg(QLatin1String("empty .rodata. not a library.")); + return Corrupt; + } +#if defined(QELFPARSER_DEBUG) + qDebug()<<"section is not program data. skipped."; +#endif + s += e_shentsize; + continue; + } + + if (sh.offset == 0 || (sh.offset + sh.size) > fdlen) { + if (lib) + lib->errorString = QLibrary::tr("'%1' is an invalid ELF object (%2)").arg(library) + .arg(QLatin1String("missing section data. This is not a library.")); + return Corrupt; + } + *pos = sh.offset; + *sectionlen = sh.size - 1; + if (shnam[1] == 'q') + return Ok; + } + s += e_shentsize; + } + return NoQtSection; +} + +QT_END_NAMESPACE + diff --git a/src/corelib/plugin/qelfparser_p.h b/src/corelib/plugin/qelfparser_p.h new file mode 100644 index 0000000..380d5a1 --- /dev/null +++ b/src/corelib/plugin/qelfparser_p.h @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QELFPARSER_P_H +#define QELFPARSER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +class QString; +class QLibraryPrivate; + +typedef quint16 qelfhalf_t; +typedef quint32 qelfword_t; +typedef quintptr qelfoff_t; +typedef quintptr qelfaddr_t; + +class QElfParser +{ +public: + enum {Ok = 0, NotElf = 1, NoQtSection = 2, Corrupt = 3}; + enum {ElfLittleEndian = 0, ElfBigEndian = 1}; + + struct ElfSectionHeader + { + qelfword_t name; + qelfword_t type; + qelfoff_t offset; + qelfword_t size; + }; + + int m_endian; + int m_bits; + int m_stringTableFileOffset; + + template + T read(const char *s) + { + if (m_endian == ElfBigEndian) + return qFromBigEndian(reinterpret_cast(s)); + else + return qFromLittleEndian(reinterpret_cast(s)); + } + + 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); +}; + +QT_END_NAMESPACE + +#endif // QELFPARSER_P_H + diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 1ca9d70..8f82cc4 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -38,7 +38,6 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - #include "qplatformdefs.h" #include "qlibrary.h" @@ -61,6 +60,7 @@ #include #include #include +#include "qelfparser_p.h" QT_BEGIN_NAMESPACE @@ -365,11 +365,31 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB fdlen = data.size(); } - // verify that the pattern is present in the plugin + /* + ELF binaries on GNU, have .qplugin sections. + */ + long pos = 0; const char pattern[] = "pattern=QT_PLUGIN_VERIFICATION_DATA"; const ulong plen = qstrlen(pattern); - long pos = qt_find_pattern(filedata, fdlen, pattern, plen); - +#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) + 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); diff --git a/tests/auto/qpluginloader/elftest/.gitattributes b/tests/auto/qpluginloader/elftest/.gitattributes new file mode 100644 index 0000000..891192c --- /dev/null +++ b/tests/auto/qpluginloader/elftest/.gitattributes @@ -0,0 +1,10 @@ +corrupt1.elf64.so set -crlf -diff +corrupt2.elf64.so set -crlf -diff +corrupt3.elf64.so set -crlf -diff +debugobj.so set -crlf -diff +garbage1.so set -crlf -diff +garbage2.so set -crlf -diff +garbage3.so set -crlf -diff +garbage4.so set -crlf -diff +garbage5.so set -crlf -diff + diff --git a/tests/auto/qpluginloader/elftest/corrupt1.elf64.so b/tests/auto/qpluginloader/elftest/corrupt1.elf64.so new file mode 100755 index 0000000..12ce736 Binary files /dev/null and b/tests/auto/qpluginloader/elftest/corrupt1.elf64.so differ diff --git a/tests/auto/qpluginloader/elftest/corrupt2.elf64.so b/tests/auto/qpluginloader/elftest/corrupt2.elf64.so new file mode 100755 index 0000000..11fdc2c Binary files /dev/null and b/tests/auto/qpluginloader/elftest/corrupt2.elf64.so differ diff --git a/tests/auto/qpluginloader/elftest/corrupt3.elf64.so b/tests/auto/qpluginloader/elftest/corrupt3.elf64.so new file mode 100755 index 0000000..94a2bc3 Binary files /dev/null and b/tests/auto/qpluginloader/elftest/corrupt3.elf64.so differ diff --git a/tests/auto/qpluginloader/elftest/debugobj.so b/tests/auto/qpluginloader/elftest/debugobj.so new file mode 100644 index 0000000..f0ee056 Binary files /dev/null and b/tests/auto/qpluginloader/elftest/debugobj.so differ diff --git a/tests/auto/qpluginloader/elftest/garbage1.so b/tests/auto/qpluginloader/elftest/garbage1.so new file mode 100644 index 0000000..0c74530 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage1.so @@ -0,0 +1,4 @@ +pcdL+&&e= +oÒʎI ٝmg]!Z +L')t +N(e P)Y8G 6-y "Zk4?^n5$Y=#y \ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage2.so b/tests/auto/qpluginloader/elftest/garbage2.so new file mode 100644 index 0000000..c06338e --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage2.so @@ -0,0 +1 @@ +v.YtKW3 \ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage3.so b/tests/auto/qpluginloader/elftest/garbage3.so new file mode 100644 index 0000000..a24c523 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage3.so @@ -0,0 +1 @@ +ȂT-ڥ 쾜i8_xI׮x=4@[BKS$ \ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage4.so b/tests/auto/qpluginloader/elftest/garbage4.so new file mode 100644 index 0000000..4f45cf5 --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage4.so @@ -0,0 +1 @@ + !\~Uu:9T+91QEǚxng5zh^t'mm*ˈdXH;vw+G 9L0! \ No newline at end of file diff --git a/tests/auto/qpluginloader/elftest/garbage5.so b/tests/auto/qpluginloader/elftest/garbage5.so new file mode 100644 index 0000000..f8c0a1d --- /dev/null +++ b/tests/auto/qpluginloader/elftest/garbage5.so @@ -0,0 +1,2 @@ +Q +-9 \ No newline at end of file diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp index 1e382b8..46fce5e 100644 --- a/tests/auto/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp @@ -123,6 +123,9 @@ private slots: void loadHints(); void deleteinstanceOnUnload(); void checkingStubsFromDifferentDrives(); + void loadDebugObj(); + void loadCorruptElf(); + void loadGarbage(); }; tst_QPluginLoader::tst_QPluginLoader() @@ -350,5 +353,54 @@ void tst_QPluginLoader::checkingStubsFromDifferentDrives() #endif//Q_OS_SYMBIAN } +void tst_QPluginLoader::loadDebugObj() +{ +#if defined (__ELF__) + QVERIFY(QFile::exists(SRCDIR "elftest/debugobj.so")); + QPluginLoader lib1(SRCDIR "elftest/debugobj.so"); + QCOMPARE(lib1.load(), false); +#endif +} + +void tst_QPluginLoader::loadCorruptElf() +{ +#if defined (__ELF__) +if (sizeof(void*) == 8) { + QVERIFY(QFile::exists(SRCDIR "elftest/corrupt1.elf64.so")); + + QPluginLoader lib1(SRCDIR "elftest/corrupt1.elf64.so"); + QCOMPARE(lib1.load(), false); + QVERIFY(lib1.errorString().contains("not an ELF object")); + + QPluginLoader lib2(SRCDIR "elftest/corrupt2.elf64.so"); + QCOMPARE(lib2.load(), false); + QVERIFY(lib2.errorString().contains("invalid")); + + QPluginLoader lib3(SRCDIR "elftest/corrupt3.elf64.so"); + QCOMPARE(lib3.load(), false); + QVERIFY(lib3.errorString().contains("invalid")); +} else if (sizeof(void*) == 4) { + QPluginLoader libW(SRCDIR "elftest/corrupt3.elf64.so"); + QCOMPARE(libW.load(), false); + QVERIFY(libW.errorString().contains("architecture")); +} else { + QFAIL("Please port QElfParser to this platform or blacklist this test."); +} +#endif +} + +void tst_QPluginLoader::loadGarbage() +{ +#if defined (Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) + for (int i=0; i<5; i++) { + QPluginLoader lib(QString(SRCDIR "elftest/garbage%1.so").arg(i)); + QCOMPARE(lib.load(), false); +#ifdef SHOW_ERRORS + qDebug() << lib.errorString(); +#endif + } +#endif +} + QTEST_APPLESS_MAIN(tst_QPluginLoader) #include "tst_qpluginloader.moc" -- cgit v0.12