diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-10-28 07:27:24 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-10-29 10:07:24 (GMT) |
commit | c76f9f15d1c604cdf3d68d2147a4a06d227871fa (patch) | |
tree | b92a53c12a38e7f8282ce92d47ea80c1510dd6b9 /src/gui/text/qstatictext_p.h | |
parent | cb2a108d79b09ec6ea91106e7f33826dceac4a42 (diff) | |
download | Qt-c76f9f15d1c604cdf3d68d2147a4a06d227871fa.zip Qt-c76f9f15d1c604cdf3d68d2147a4a06d227871fa.tar.gz Qt-c76f9f15d1c604cdf3d68d2147a4a06d227871fa.tar.bz2 |
Fix possible crash in QStaticText and QDeclarativeTextLayout
The QStaticTextItem held an uncounted reference to QFontEngine. The
pointer would dangle in some cases where there was no font object
referencing the engine and the cache was cleaned out (e.g. when a
new application font is added.) Properly count the reference, and also
add reference counting to userData to make it harder to shoot yourself
in the foot, since the QStaticTextItem class is now being used in
different places,
Task-number: QTBUG-14446
Reviewed-by: Martin Jones
Diffstat (limited to 'src/gui/text/qstatictext_p.h')
-rw-r--r-- | src/gui/text/qstatictext_p.h | 54 |
1 files changed, 45 insertions, 9 deletions
diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index cb60626..87ef0d5 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -68,27 +68,60 @@ public: OpenGLUserData }; - QStaticTextUserData(Type t) : type(t) {} + QStaticTextUserData(Type t) : type(t) { ref = 0; } virtual ~QStaticTextUserData() {} + QAtomicInt ref; Type type; }; class Q_GUI_EXPORT QStaticTextItem { public: - QStaticTextItem() : chars(0), numChars(0), fontEngine(0), userData(0), - useBackendOptimizations(false), userDataNeedsUpdate(0) {} - ~QStaticTextItem() { delete userData; } + QStaticTextItem() : chars(0), numChars(0), useBackendOptimizations(false), + userDataNeedsUpdate(0), m_fontEngine(0), m_userData(0) {} + + QStaticTextItem(const QStaticTextItem &other) + { + operator=(other); + } + + void operator=(const QStaticTextItem &other) + { + glyphPositions = other.glyphPositions; + glyphs = other.glyphs; + chars = other.chars; + numGlyphs = other.numGlyphs; + numChars = other.numChars; + font = other.font; + color = other.color; + useBackendOptimizations = other.useBackendOptimizations; + userDataNeedsUpdate = other.userDataNeedsUpdate; + + m_fontEngine = 0; + m_userData = 0; + setUserData(other.userData()); + setFontEngine(other.fontEngine()); + } + + ~QStaticTextItem(); void setUserData(QStaticTextUserData *newUserData) { - if (userData == newUserData) + if (m_userData == newUserData) return; - delete userData; - userData = newUserData; + if (m_userData != 0 && !m_userData->ref.deref()) + delete m_userData; + + m_userData = newUserData; + if (m_userData != 0) + m_userData->ref.ref(); } + QStaticTextUserData *userData() const { return m_userData; } + + void setFontEngine(QFontEngine *fe); + QFontEngine *fontEngine() const { return m_fontEngine; } union { QFixedPoint *glyphPositions; // 8 bytes per glyph @@ -108,14 +141,17 @@ public: // 12 bytes for pointers int numGlyphs; // 4 bytes per item int numChars; // 4 bytes per item - QFontEngine *fontEngine; // 4 bytes per item QFont font; // 8 bytes per item QColor color; // 10 bytes per item - QStaticTextUserData *userData; // 8 bytes per item char useBackendOptimizations : 1; // 1 byte per item char userDataNeedsUpdate : 1; // // ================ // 51 bytes per item + +private: // Needs special handling in setters, so private to avoid abuse + QFontEngine *m_fontEngine; // 4 bytes per item + QStaticTextUserData *m_userData; // 8 bytes per item + }; class QStaticText; |