Prevent buffer overrun when getting the glyph images

The change 35bc3dc45aacaf36a8bdfccc7627136cc2e5b185 moved some padding out
of QTextureGlyphCache into the font engines directly, however this was not
done for the DirectWrite font engine so it caused a buffer overrun.

Task-number: QTBUG-41782
Change-Id: I4e643159036f06c5edd8a742dc6694d517a47826
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@theqtcompany.com>
This commit is contained in:
Andy Shaw 2015-01-05 14:26:03 +01:00
parent 5517d1fde5
commit bb16ceac68
3 changed files with 32 additions and 3 deletions

View File

@ -515,8 +515,9 @@ QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
const QTransform &xform) const QTransform &xform)
{ {
glyph_metrics_t metrics = QFontEngine::boundingBox(t, xform); glyph_metrics_t metrics = QFontEngine::boundingBox(t, xform);
int width = (metrics.width + margin * 2 + 4).ceil().toInt() ; // This needs to be kept in sync with alphaMapBoundingBox
int height = (metrics.height + margin * 2 + 4).ceil().toInt(); int width = (metrics.width + margin * 2).ceil().toInt() ;
int height = (metrics.height + margin * 2).ceil().toInt();
UINT16 glyphIndex = t; UINT16 glyphIndex = t;
FLOAT glyphAdvance = metrics.xoff.toReal(); FLOAT glyphAdvance = metrics.xoff.toReal();
@ -699,6 +700,18 @@ QString QWindowsFontEngineDirectWrite::fontNameSubstitute(const QString &familyN
return QSettings(QLatin1String(keyC), QSettings::NativeFormat).value(familyName, familyName).toString(); return QSettings(QLatin1String(keyC), QSettings::NativeFormat).value(familyName, familyName).toString();
} }
glyph_metrics_t QWindowsFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph, QFixed pos, const QTransform &matrix, GlyphFormat format)
{
Q_UNUSED(pos);
int margin = 0;
if (format == QFontEngine::Format_A32 || format == QFontEngine::Format_ARGB)
margin = glyphMargin(QFontEngine::Format_A32);
glyph_metrics_t gm = QFontEngine::boundingBox(glyph, matrix);
gm.width += margin * 2;
gm.height += margin * 2;
return gm;
}
QT_END_NAMESPACE QT_END_NAMESPACE
#endif // QT_NO_DIRECTWRITE #endif // QT_NO_DIRECTWRITE

View File

@ -75,6 +75,7 @@ public:
glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); glyph_metrics_t boundingBox(const QGlyphLayout &glyphs);
glyph_metrics_t boundingBox(glyph_t g); glyph_metrics_t boundingBox(glyph_t g);
glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, QFixed, const QTransform &matrix, GlyphFormat);
QFixed ascent() const; QFixed ascent() const;
QFixed descent() const; QFixed descent() const;

View File

@ -289,7 +289,7 @@ private slots:
void blendARGBonRGB(); void blendARGBonRGB();
void RasterOp_NotDestination(); void RasterOp_NotDestination();
void drawTextNoHinting();
private: private:
void fillData(); void fillData();
void setPenColor(QPainter& p); void setPenColor(QPainter& p);
@ -4812,6 +4812,21 @@ void tst_QPainter::RasterOp_NotDestination()
QCOMPARE(pixel, 0xff00ffff); QCOMPARE(pixel, 0xff00ffff);
} }
void tst_QPainter::drawTextNoHinting()
{
{
QImage image(250, 250, QImage::Format_RGB32);
QPainter p(&image);
QFont font("Arial", 8);
font.setHintingPreference(QFont::PreferNoHinting);
font.setStyleStrategy(QFont::PreferAntialias);
p.setFont(font);
p.drawText(image.rect(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz");
}
// Testing for a crash when DirectWrite is used on Windows
QVERIFY(true);
}
QTEST_MAIN(tst_QPainter) QTEST_MAIN(tst_QPainter)
#include "tst_qpainter.moc" #include "tst_qpainter.moc"