diff options
author | Konstantin Ritt <ritt.ks@gmail.com> | 2014-06-18 13:24:00 +0300 |
---|---|---|
committer | Jani Heikkinen <jani.heikkinen@digia.com> | 2014-06-18 13:39:42 +0200 |
commit | 302ffa5820c05534bec9978368b3c2c1295f12a1 (patch) | |
tree | 1ad792e5c0b6d99cb90a4c03bc443afe09b3254b | |
parent | abcea1c5f06b2ea0428e08a3a71f08d39c29c2fd (diff) |
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 <eskil.abrahamsen-blomfeldt@digia.com>
-rw-r--r-- | src/gui/text/qfontengine.cpp | 27 |
1 files 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<QFontEngine *>(this)); #endif if (!face_) { - HB_Face hbFace = qHBNewFace(const_cast<QFontEngine *>(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)]; } |