diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2012-10-29 12:03:34 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-10-29 20:31:08 +0100 |
commit | 7aa0adf130447214ff3a7bb8144d35b366e94d77 (patch) | |
tree | d11ef569be3943562d779e31d525c580906c6966 | |
parent | c21564b1ef2fe7959907ef9fefe44fad58738710 (diff) |
QFontEngineMulti: Fix possible crash in stringToCMap()
in case when the layout is partially initialized.
We shouldn't access any data except of indices
if GlyphIndicesOnly flag has been passed in.
Change-Id: I264689b498e0f9de8b5c040d47dbae4f6ef391c4
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
-rw-r--r-- | src/gui/text/qfontengine.cpp | 7 | ||||
-rw-r--r-- | tests/auto/gui/text/qfontmetrics/qfontmetrics.pro | 2 | ||||
-rw-r--r-- | tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp | 34 |
3 files changed, 39 insertions, 4 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index bdcf166243..fa4e7a75bc 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1370,7 +1370,9 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, bool surrogate = (str[i].isHighSurrogate() && i < len-1 && str[i+1].isLowSurrogate()); uint ucs4 = surrogate ? QChar::surrogateToUcs4(str[i], str[i+1]) : str[i].unicode(); if (glyphs->glyphs[glyph_pos] == 0 && str[i].category() != QChar::Separator_Line) { - QGlyphLayoutInstance tmp = glyphs->instance(glyph_pos); + QGlyphLayoutInstance tmp; + if (!(flags & GlyphIndicesOnly)) + tmp = glyphs->instance(glyph_pos); for (int x=1; x < engines.size(); ++x) { if (engines.at(x) == 0 && !shouldLoadFontEngineForCharacter(x, ucs4)) continue; @@ -1400,9 +1402,8 @@ bool QFontEngineMulti::stringToCMap(const QChar *str, int len, } // ensure we use metrics from the 1st font when we use the fallback image. - if (!glyphs->glyphs[glyph_pos]) { + if (!(flags & GlyphIndicesOnly) && !glyphs->glyphs[glyph_pos]) glyphs->setInstance(glyph_pos, tmp); - } } if (surrogate) diff --git a/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro b/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro index ef08458c56..88436f6a0e 100644 --- a/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro +++ b/tests/auto/gui/text/qfontmetrics/qfontmetrics.pro @@ -1,7 +1,7 @@ CONFIG += testcase CONFIG += parallel_test TARGET = tst_qfontmetrics -QT += testlib +QT += testlib core-private gui-private SOURCES += tst_qfontmetrics.cpp RESOURCES += testfont.qrc DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0 diff --git a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp index 4f502ae5f2..b457e17b48 100644 --- a/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp @@ -44,6 +44,7 @@ #include <qfont.h> #include <qfontmetrics.h> #include <qfontdatabase.h> +#include <private/qfontengine_p.h> #include <qstringlist.h> #include <qlist.h> @@ -279,6 +280,39 @@ void tst_QFontMetrics::inFontUcs4() QVERIFY(fm.inFontUcs4(0x1D7FF)); } + { + QFontEngine *engine = QFontPrivate::get(font)->engineForScript(QUnicodeTables::Common); + QGlyphLayout glyphs; + glyphs.numGlyphs = 3; + uint buf[3]; + glyphs.glyphs = buf; + + QString string; + { + string.append(QChar::highSurrogate(0x1D7FF)); + string.append(QChar::lowSurrogate(0x1D7FF)); + + glyphs.numGlyphs = 3; + glyphs.glyphs[0] = 0; + QVERIFY(engine->stringToCMap(string.constData(), string.size(), + &glyphs, &glyphs.numGlyphs, + QFontEngine::GlyphIndicesOnly)); + QCOMPARE(glyphs.numGlyphs, 1); + QCOMPARE(glyphs.glyphs[0], uint(1)); + } + { + string.clear(); + string.append(QChar::ObjectReplacementCharacter); + + glyphs.numGlyphs = 3; + glyphs.glyphs[0] = 0; + QVERIFY(engine->stringToCMap(string.constData(), string.size(), + &glyphs, &glyphs.numGlyphs, + QFontEngine::GlyphIndicesOnly)); + QVERIFY(glyphs.glyphs[0] != 1); + } + } + QFontDatabase::removeApplicationFont(id); } |