From 7aa0adf130447214ff3a7bb8144d35b366e94d77 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 29 Oct 2012 12:03:34 +0200 Subject: 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 --- src/gui/text/qfontengine.cpp | 7 +++-- tests/auto/gui/text/qfontmetrics/qfontmetrics.pro | 2 +- .../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 #include #include +#include #include #include @@ -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); } -- cgit v1.2.3