summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2014-06-18 13:24:00 +0300
committerJani Heikkinen <jani.heikkinen@digia.com>2014-06-18 13:39:42 +0200
commit302ffa5820c05534bec9978368b3c2c1295f12a1 (patch)
tree1ad792e5c0b6d99cb90a4c03bc443afe09b3254b /src
parentabcea1c5f06b2ea0428e08a3a71f08d39c29c2fd (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>
Diffstat (limited to 'src')
-rw-r--r--src/gui/text/qfontengine.cpp27
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)];
}