From 302ffa5820c05534bec9978368b3c2c1295f12a1 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 18 Jun 2014 13:24:00 +0300 Subject: Fix crash when reusing HB_Face in another font engine After 717d39ac083e80, if HB_Face was instantiated by QFontEngineFT A and then used by QFontEngineFT B, whilst A already destroyed, a crash occurs in hb_getSFntTable() due to accessing a stale pointer. Task-number: QTBUG-39278 Change-Id: I3428669a311f49cdda1725b778f45219cbcf470d Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine.cpp | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 078e16574f..8adbb31a55 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -177,9 +177,13 @@ static const HB_FontClass hb_fontClass = { static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length) { - QFontEngine *fe = (QFontEngine *)font; - Q_ASSERT(fe->faceData.get_font_table); - if (!fe->faceData.get_font_table(fe->faceData.user_data, tableTag, buffer, length)) + QFontEngine::FaceData *data = (QFontEngine::FaceData *)font; + Q_ASSERT(data); + + qt_get_font_table_func_t get_font_table = data->get_font_table; + Q_ASSERT(get_font_table); + + if (!get_font_table(data->user_data, tableTag, buffer, length)) return HB_Err_Invalid_Argument; return HB_Err_Ok; } @@ -287,8 +291,11 @@ void *QFontEngine::harfbuzzFont() const #endif if (!font_) { HB_Face hbFace = (HB_Face)harfbuzzFace(); - if (hbFace->font_for_init != 0) + if (hbFace->font_for_init) { + void *data = hbFace->font_for_init; q_check_ptr(qHBLoadFace(hbFace)); + free(data); + } HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec)); Q_CHECK_PTR(hbFont); @@ -319,7 +326,12 @@ void *QFontEngine::harfbuzzFace() const return hb_qt_face_get_for_engine(const_cast(this)); #endif if (!face_) { - HB_Face hbFace = qHBNewFace(const_cast(this), hb_getSFntTable); + QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData)); + Q_CHECK_PTR(data); + data->user_data = faceData.user_data; + data->get_font_table = faceData.get_font_table; + + HB_Face hbFace = qHBNewFace(data, hb_getSFntTable); Q_CHECK_PTR(hbFace); hbFace->isSymbolFont = symbol; @@ -372,8 +384,11 @@ bool QFontEngine::supportsScript(QChar::Script script) const } #endif HB_Face hbFace = (HB_Face)harfbuzzFace(); - if (hbFace->font_for_init != 0) + if (hbFace->font_for_init) { + void *data = hbFace->font_for_init; q_check_ptr(qHBLoadFace(hbFace)); + free(data); + } return hbFace->supported_scripts[script_to_hbscript(script)]; } -- cgit v1.2.3