From 84be1bd4d3ed8d2d9e65301649bc841ea4197fe2 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Tue, 14 Jan 2014 18:27:33 +0200 Subject: Fix crash due to a stale pointer dereferencing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HB face caching mechanism introduced in 227e9a40cfeb7e00658cd3 wasn't complete due that fact that HB-NG doesn't parse the entire font table at once but rather references a table on-demand. This incompleteness caused a crash in case the engine doesn't get cached or when it removed from the cache and then re-used. Task-number: QTBUG-36099 Change-Id: I7816836107655ce7cf6eb9683bb5dc7f892f9cd1 Reviewed-by: Lisandro Damián Nicanor Pérez Meyer Reviewed-by: Michael Krasnyk Reviewed-by: Lars Knoll Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qharfbuzzng.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src/gui/text/qharfbuzzng.cpp') diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp index b4ab5856df..d2e7df9c10 100644 --- a/src/gui/text/qharfbuzzng.cpp +++ b/src/gui/text/qharfbuzzng.cpp @@ -623,19 +623,22 @@ hb_font_funcs_t *hb_qt_get_font_funcs() static hb_blob_t * -_hb_qt_get_font_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data) +_hb_qt_reference_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data) { - QFontEngine *fe = (QFontEngine *)user_data; - Q_ASSERT(fe); + QFontEngine::FaceData *data = (QFontEngine::FaceData *)user_data; + Q_ASSERT(data); + + qt_get_font_table_func_t get_font_table = data->get_font_table; + Q_ASSERT(get_font_table); uint length = 0; - if (Q_UNLIKELY(!fe->getSfntTableData(tag, 0, &length) || length == 0)) + if (Q_UNLIKELY(!get_font_table(data->user_data, tag, 0, &length) || length == 0)) return hb_blob_get_empty(); char *buffer = (char *)malloc(length); Q_CHECK_PTR(buffer); - if (Q_UNLIKELY(!fe->getSfntTableData(tag, reinterpret_cast(buffer), &length))) + if (Q_UNLIKELY(!get_font_table(data->user_data, tag, reinterpret_cast(buffer), &length))) length = 0; return hb_blob_create(const_cast(buffer), length, @@ -646,9 +649,14 @@ _hb_qt_get_font_table(hb_face_t * /*face*/, hb_tag_t tag, void *user_data) static inline hb_face_t * _hb_qt_face_create(QFontEngine *fe) { - hb_face_t *face; + Q_ASSERT(fe); + + QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData)); + Q_CHECK_PTR(data); + data->user_data = fe->faceData.user_data; + data->get_font_table = fe->faceData.get_font_table; - face = hb_face_create_for_tables(_hb_qt_get_font_table, (void *)fe, NULL); + hb_face_t *face = hb_face_create_for_tables(_hb_qt_reference_table, (void *)data, free); if (Q_UNLIKELY(hb_face_is_immutable(face))) { hb_face_destroy(face); return NULL; -- cgit v1.2.3