summaryrefslogtreecommitdiff
path: root/sw/inc/txatbase.hxx
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2014-10-22 23:45:22 +0200
committerMichael Stahl <mstahl@redhat.com>2014-10-23 00:04:19 +0200
commit72f368f6bfedb680ffcbd1c7fe28e8fc6d19ad2b (patch)
treebc1c10f8d29b9e3147b12a859fa1665b8fe65d76 /sw/inc/txatbase.hxx
parentbc87f12c6a045203d3bb3c0d0e38693c25efa1f9 (diff)
sw: fix undefined casts of SwTxtInputFld
... as reported by sberg via UBSan in CppunitTest_sw_mailmerge: > sw/source/core/txtnode/thints.cxx:3207:38: runtime error: downcast of address 0x000003cadcb0 which does not point to an object of type 'SwTxtAttrNesting' > 0x000003cadcb0: note: object is of type 'SwTxtInputFld' > #0 in SwpHints::TryInsertHint(SwTxtAttr*, SwTxtNode&, unsigned short) sw/source/core/txtnode/thints.cxx:3207:13 > #1 in SwTxtNode::InsertHint(SwTxtAttr*, unsigned short) sw/source/core/txtnode/thints.cxx:1583:25 > #2 in SwTxtNode::SetAttr(SfxItemSet const&, int, int, unsigned short) sw/source/core/txtnode/thints.cxx:1943:39 > #3 in SwRegHistory::InsertItems(SfxItemSet const&, int, int, unsigned short) sw/source/core/undo/rolbck.cxx:1390:28 > #4 in (anonymous namespace)::lcl_InsAttr(SwDoc*, SwPaM const&, SfxItemSet const&, unsigned short, SwUndoAttr*, bool) sw/source/core/doc/DocumentContentOperationsManager.cxx:1169:28 > #5 in sw::DocumentContentOperationsManager::InsertPoolItem(SwPaM const&, SfxPoolItem const&, unsigned short, bool) sw/source/core/doc/DocumentContentOperationsManager.cxx:3041:23 > #6 in SwXTextField::attach(com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&) sw/source/core/unocore/unofield.cxx:1966:13 > #7 in non-virtual thunk to SwXTextField::attach(com::sun::star::uno::Reference<com::sun::star::text::XTextRange> const&) sw/source/core/unocore/unofield.cxx:2061:1 The SwTxtInputFld is unusual because it's both a field and has a range; let's try to use virtual inheritance to inherit both from SwTxtFld and SwTxtAttrNesting. Sadly requires dynamic_cast everywhere. Change-Id: I69f834d2b78ef7cdaac1f554bd80711084efcd02
Diffstat (limited to 'sw/inc/txatbase.hxx')
-rw-r--r--sw/inc/txatbase.hxx21
1 files changed, 20 insertions, 1 deletions
diff --git a/sw/inc/txatbase.hxx b/sw/inc/txatbase.hxx
index 222857da0d0d..830d097128c4 100644
--- a/sw/inc/txatbase.hxx
+++ b/sw/inc/txatbase.hxx
@@ -121,7 +121,7 @@ public:
};
-class SwTxtAttrEnd : public SwTxtAttr
+class SwTxtAttrEnd : public virtual SwTxtAttr
{
protected:
sal_Int32 m_nEnd;
@@ -132,6 +132,15 @@ public:
virtual sal_Int32* GetEnd() SAL_OVERRIDE;
};
+// attribute that must not overlap others
+class SwTxtAttrNesting : public SwTxtAttrEnd
+{
+protected:
+ SwTxtAttrNesting( SfxPoolItem & i_rAttr,
+ const sal_Int32 i_nStart, const sal_Int32 i_nEnd );
+ virtual ~SwTxtAttrNesting();
+};
+
inline const sal_Int32* SwTxtAttr::End() const
{
return const_cast<SwTxtAttr * >(this)->GetEnd();
@@ -227,6 +236,16 @@ inline const SwFmtMeta& SwTxtAttr::GetMeta() const
return (const SwFmtMeta&)(*m_pAttr);
}
+// these should be static_casts but with virtual inheritance it's not possible
+template<typename T, typename S> inline T static_txtattr_cast(S * s)
+{
+ return dynamic_cast<T>(s);
+}
+template<typename T, typename S> inline T static_txtattr_cast(S & s)
+{
+ return dynamic_cast<T>(s);
+}
+
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */