diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2016-09-28 12:18:11 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2016-09-29 12:43:19 +0000 |
commit | 462f6029ed7ab34b76afc009b95134d4e51a8e18 (patch) | |
tree | f61eec5d0c4abfd1d128edbfc9e1fcd1eaa4a68b /tests/auto | |
parent | 422838685c31d9b57133a8711bfd5db92095d96d (diff) |
Fix crash when doing many text layouts with superscript/subscript
After e109b8a0f3c89c595f0da689e7ee847130e2ee47, it is possible
that the cache will be flushed as a result of inserting a new
font rather than just when the timer event triggers. When doing
superscript and subscript text layouts, we would first get
a regular font engine, then a scaled one, and then reference
the regular font engine *after* getting the scaled one. If the
regular font engine was deleted as a result of inserting the scaled
one, we would get a dangling pointer and crash.
The situation was improved by 49926bb9ef983d4c19aed635a00b388252c065e4.
You would now to switch between 256 different fonts in the layout
in order to trigger it. The test in the commit will trigger the
crash even with this change.
[ChangeLog][Qt Gui][Text] Fixed a crash that could happen if you
were doing many different text layouts with different fonts
and superscript or subscript alignment.
Task-number: QTBUG-53911
Change-Id: Ia33108252e030eff25924ef1b7c10b9d59b5bc8c
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index e778232461..84d58191c0 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -143,6 +143,7 @@ private slots: void cursorInNonStopChars(); void nbsp(); void noModificationOfInputString(); + void superscriptCrash_qtbug53911(); private: QFont testFont; @@ -2209,5 +2210,61 @@ void tst_QTextLayout::noModificationOfInputString() } } +void tst_QTextLayout::superscriptCrash_qtbug53911() +{ + static int fontSizes = 64; + static QString layoutText = "THIS IS SOME EXAMPLE TEXT THIS IS SOME EXAMPLE TEXT"; + + QList<QTextLayout*> textLayouts; + for (int i = 0; i < fontSizes; ++i) { + for (int j = 0; j < 4; ++j) { + QTextLayout* newTextLayout = new QTextLayout(); + newTextLayout->setText(layoutText); + QList<QTextLayout::FormatRange> formatRanges; + QTextLayout::FormatRange formatRange; + + formatRange.format.setFont(QFont()); + formatRange.format.setFontPointSize(i + 5); + + switch (j) { + case 0: + formatRange.format.setFontWeight(QFont::Normal); + formatRange.format.setFontItalic(false); + break; + case 1: + formatRange.format.setFontWeight(QFont::Bold); + formatRange.format.setFontItalic(false); + break; + case 2: + formatRange.format.setFontWeight(QFont::Bold); + formatRange.format.setFontItalic(true); + break; + case 3: + formatRange.format.setFontWeight(QFont::Normal); + formatRange.format.setFontItalic(true); + break; + } + + formatRange.format.setVerticalAlignment( QTextCharFormat::AlignSuperScript); + + formatRange.start = 0; + formatRange.length = layoutText.size(); + formatRanges << formatRange; + newTextLayout->setAdditionalFormats(formatRanges); + + textLayouts.push_front(newTextLayout); + } + } + + // This loop would crash before fix for QTBUG-53911 + foreach (QTextLayout *textLayout, textLayouts) { + textLayout->beginLayout(); + while (textLayout->createLine().isValid()); + textLayout->endLayout(); + } + + qDeleteAll(textLayouts); +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" |