summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@digia.com>2013-04-22 09:05:52 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-04-25 09:03:53 +0200
commit17f263905f00dfd0f01d9f5226ac06b07aa9d421 (patch)
tree74a3c528a0fa31122669d63d177d4bde206fb5cf
parent64e25b0dd9ae2f289f14583827070594517adebb (diff)
downloadqt4-tools-17f263905f00dfd0f01d9f5226ac06b07aa9d421.tar.gz
Fixed potential invalid memory access in OpenGL engine glyph cache.
We need to clamp glyph_height to prevent from overflowing the texture cache. A slightly similar issue was fixed for glyph_width in change 9520674b0f02aac55da6. Also, we should only increment the y_offset in the place where we check for an overflow. Task-number: QTBUG-26649 Change-Id: I297191b2ffd68a636bfced7f5284fd3b9383e988 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
-rw-r--r--src/opengl/qpaintengine_opengl.cpp20
1 files changed, 9 insertions, 11 deletions
diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp
index 2cc0d351a4..3aea52ac5d 100644
--- a/src/opengl/qpaintengine_opengl.cpp
+++ b/src/opengl/qpaintengine_opengl.cpp
@@ -4810,7 +4810,7 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
int strip_height = qt_next_power_of_two(qRound(fontEngine->ascent().toReal() + fontEngine->descent().toReal())+2);
font_tex->x_offset = x_margin;
font_tex->y_offset += strip_height;
- if (font_tex->y_offset >= font_tex->height) {
+ if (font_tex->y_offset + strip_height > font_tex->height) {
// get hold of the old font texture
uchar *old_tex_data = font_tex->data;
int old_tex_height = font_tex->height;
@@ -4838,6 +4838,8 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
}
}
+ glyph_height = qMin(glyph_height, glyph_im.height());
+
QGLGlyphCoord *qgl_glyph = new QGLGlyphCoord;
qgl_glyph->x = qreal(font_tex->x_offset) / font_tex->width;
qgl_glyph->y = qreal(font_tex->y_offset) / font_tex->height;
@@ -4855,8 +4857,8 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
if (!glyph_im.isNull()) {
int idx = 0;
- uchar *tex_data = (uchar *) malloc(glyph_width*glyph_im.height()*2);
- memset(tex_data, 0, glyph_width*glyph_im.height()*2);
+ uchar *tex_data = (uchar *) malloc(glyph_width*glyph_height*2);
+ memset(tex_data, 0, glyph_width*glyph_height*2);
bool is8BitGray = false;
#ifdef Q_WS_QPA
@@ -4866,7 +4868,7 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
#endif
glyph_im = glyph_im.convertToFormat(QImage::Format_Indexed8);
int cacheLineStart = (font_tex->x_offset + font_tex->y_offset*font_tex->width)*2;
- for (int y=0; y<glyph_im.height(); ++y) {
+ for (int y=0; y<glyph_height; ++y) {
uchar *s = (uchar *) glyph_im.scanLine(y);
int lineStart = idx;
for (int x=0; x<glyph_im.width(); ++x) {
@@ -4883,16 +4885,12 @@ void QGLGlyphCache::cacheGlyphs(QGLContext *context, QFontEngine *fontEngine,
cacheLineStart += font_tex->width*2;
}
glTexSubImage2D(GL_TEXTURE_2D, 0, font_tex->x_offset, font_tex->y_offset,
- glyph_width, glyph_im.height(),
+ glyph_width, glyph_height,
GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, tex_data);
free(tex_data);
}
- if (font_tex->x_offset + glyph_width + x_margin > font_tex->width) {
- font_tex->x_offset = x_margin;
- font_tex->y_offset += glyph_height + y_margin;
- } else {
- font_tex->x_offset += glyph_width + x_margin;
- }
+
+ font_tex->x_offset += glyph_width + x_margin;
cache->insert(glyphs[i], qgl_glyph);
}