summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qharfbuzzng.cpp
diff options
context:
space:
mode:
authorKonstantin Ritt <ritt.ks@gmail.com>2014-01-14 18:27:33 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-16 20:38:42 +0100
commit84be1bd4d3ed8d2d9e65301649bc841ea4197fe2 (patch)
tree5af8202cc36f092f2a7f40e075e2ac53d0288c06 /src/gui/text/qharfbuzzng.cpp
parent2565ef220b9f261fc2d62869b8d38625e41bc6fd (diff)
Fix crash due to a stale pointer dereferencing
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 <perezmeyer@gmail.com> Reviewed-by: Michael Krasnyk <michael.krasnyk@gmail.com> Reviewed-by: Lars Knoll <lars.knoll@digia.com> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'src/gui/text/qharfbuzzng.cpp')
-rw-r--r--src/gui/text/qharfbuzzng.cpp22
1 files changed, 15 insertions, 7 deletions
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<uchar *>(buffer), &length)))
+ if (Q_UNLIKELY(!get_font_table(data->user_data, tag, reinterpret_cast<uchar *>(buffer), &length)))
length = 0;
return hb_blob_create(const_cast<const char *>(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;