QFontEngineMulti: Fix possible crash in stringToCMap()
authorKonstantin Ritt <ritt.ks@gmail.com>
Mon, 29 Oct 2012 10:03:34 +0000 (12:03 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Mon, 29 Oct 2012 19:31:08 +0000 (20:31 +0100)
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>
src/gui/text/qfontengine.cpp
tests/auto/gui/text/qfontmetrics/qfontmetrics.pro
tests/auto/gui/text/qfontmetrics/tst_qfontmetrics.cpp

index bdcf166..fa4e7a7 100644 (file)
@@ -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)
index ef08458..88436f6 100644 (file)
@@ -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
index 4f502ae..b457e17 100644 (file)
@@ -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);
 }