[PATCH] Fix for sw_filter_test crash due to ambiguous FieldEntry destructor

Kristian Rietveld kris at lanedo.com
Sun Jul 22 02:25:27 PDT 2012

(Please keep me on CC as I am not subscribed to the list)

Hi all,

I have been building LibreOffice using Clang on Mac OS X Lion again, now 
that it is possible to get a working build using Clang on Linux.

During the build, however, the "sw_filters_test" unit test crashes. The 
crash happens in rtl_string_release from the FieldEntry (the one in 
sw/source/file/ww8/ww8par.hxx) destructor. The FieldEntry destructor is 
called through a dyld stub.

After reading assembly code I figured that the FieldEntry destructor 
being executed does not match the FieldEntry's fields. What was already 
suspicious above is that rtl_string_release is being called even though 
this FieldEntry uses OUStrings.

 From the assembly code I guess the FieldEntry destructor being executed 
is actually the one in registry/source/reflwrit.cxx.  So my impression 
is that the dynamic linker on OS X is simply calling the wrong 
destructor (the symbols have the same name).

To fix this, I can think of either putting the WW8 FieldEntry in a 
namespace, or renaming it to WW8FieldEntry. Since no namespaces were 
used in the current code, I decided to rename the class.

A patch is attached and I verified that it fixes the crashing unit test 
for me. If people have a better or preferred way to fix this, please let 
me know and I will update the patch accordingly.



-------------- next part --------------
>From 1bfb0a0d984b955fe5df9fd6fa898c985aea305b Mon Sep 17 00:00:00 2001
From: Kristian Rietveld <kris at lanedo.com>
Date: Sun, 22 Jul 2012 11:19:28 +0200
Subject: [PATCH] Rename FieldEntry to WW8FieldEntry

When compiled with Clang on OS X, the OS X dynamic linker appears to be
confused about which FieldEntry destructor to call at runtime. In some
cases, the FieldEntry destructor in register/source/reflwrit.cxx is
called instead (both destructors have the same symbol name). This patch
avoids this problem.

Change-Id: I7d69894318cb8fda0a7c5a9b1c2ff3ca0d47a37c
 sw/source/filter/ww8/ww8par.hxx  |   16 ++++++++--------
 sw/source/filter/ww8/ww8par5.cxx |   26 +++++++++++++-------------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index dde6d15..9215369 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -456,7 +456,7 @@ namespace sw
-class FieldEntry
+class WW8FieldEntry
         ::rtl::OUString msBookmarkName;
@@ -468,10 +468,10 @@ class FieldEntry
         sw::hack::Position maStartPos;
         sal_uInt16 mnFieldId;
         sal_uLong mnObjLocFc;
-        FieldEntry(SwPosition &rPos, sal_uInt16 nFieldId) throw();
-        FieldEntry(const FieldEntry &rOther) throw();
-        FieldEntry &operator=(const FieldEntry &rOther) throw();
-        void Swap(FieldEntry &rOther) throw();
+        WW8FieldEntry(SwPosition &rPos, sal_uInt16 nFieldId) throw();
+        WW8FieldEntry(const WW8FieldEntry &rOther) throw();
+        WW8FieldEntry &operator=(const WW8FieldEntry &rOther) throw();
+        void Swap(WW8FieldEntry &rOther) throw();
         SwNodeIndex GetPtNode() { return maStartPos.GetPtNode(); };
         xub_StrLen GetPtCntnt() { return maStartPos.GetPtCntnt(); };
@@ -494,7 +494,7 @@ private:
     WW8PLCFxSaveAll maPLCFxSave;
     SwPosition maTmpPos;
     std::deque<bool> maOldApos;
-    std::deque<FieldEntry> maOldFieldStack;
+    std::deque<WW8FieldEntry> maOldFieldStack;
     SwWW8FltControlStack* mpOldStck;
     SwWW8FltAnchorStack* mpOldAnchorStck;
     sw::util::RedlineStack *mpOldRedlines;
@@ -985,8 +985,8 @@ private:
     where the end point will fall, to do so fully correctly duplicates the
     main logic of the filter itself.
-    std::deque<FieldEntry> maFieldStack;
-    typedef std::deque<FieldEntry>::const_iterator mycFieldIter;
+    std::deque<WW8FieldEntry> maFieldStack;
+    typedef std::deque<WW8FieldEntry>::const_iterator mycFieldIter;
     A stack of open footnotes. Should only be one in it at any time.
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index bffc240..412fb14 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -413,7 +413,7 @@ long SwWW8ImplReader::Read_Book(WW8PLCFManResult*)
     SwPosition aStart(*pPaM->GetPoint());
     if (!maFieldStack.empty())
-        const FieldEntry &rTest = maFieldStack.back();
+        const WW8FieldEntry &rTest = maFieldStack.back();
         aStart = rTest.maStartPos;
@@ -826,56 +826,56 @@ bool AcceptableNestedField(sal_uInt16 nFieldCode)
-FieldEntry::FieldEntry(SwPosition &rPos, sal_uInt16 nFieldId) throw()
+WW8FieldEntry::WW8FieldEntry(SwPosition &rPos, sal_uInt16 nFieldId) throw()
     : maStartPos(rPos), mnFieldId(nFieldId), mnObjLocFc(0)
-FieldEntry::FieldEntry(const FieldEntry &rOther) throw()
+WW8FieldEntry::WW8FieldEntry(const WW8FieldEntry &rOther) throw()
     : maStartPos(rOther.maStartPos), mnFieldId(rOther.mnFieldId), mnObjLocFc(rOther.mnObjLocFc)
-void FieldEntry::Swap(FieldEntry &rOther) throw()
+void WW8FieldEntry::Swap(WW8FieldEntry &rOther) throw()
     std::swap(maStartPos, rOther.maStartPos);
     std::swap(mnFieldId, rOther.mnFieldId);
-FieldEntry &FieldEntry::operator=(const FieldEntry &rOther) throw()
+WW8FieldEntry &WW8FieldEntry::operator=(const WW8FieldEntry &rOther) throw()
-    FieldEntry aTemp(rOther);
+    WW8FieldEntry aTemp(rOther);
     return *this;
-::rtl::OUString FieldEntry::GetBookmarkName()
+::rtl::OUString WW8FieldEntry::GetBookmarkName()
     return msBookmarkName;
-::rtl::OUString FieldEntry::GetBookmarkCode()
+::rtl::OUString WW8FieldEntry::GetBookmarkCode()
     return msMarkCode;
-void FieldEntry::SetBookmarkName(::rtl::OUString bookmarkName)
+void WW8FieldEntry::SetBookmarkName(::rtl::OUString bookmarkName)
-void FieldEntry::SetBookmarkType(::rtl::OUString bookmarkType)
+void WW8FieldEntry::SetBookmarkType(::rtl::OUString bookmarkType)
-void FieldEntry::SetBookmarkCode(::rtl::OUString bookmarkCode)
+void WW8FieldEntry::SetBookmarkCode(::rtl::OUString bookmarkCode)
     msMarkCode = bookmarkCode;
-::sw::mark::IFieldmark::parameter_map_t& FieldEntry::getParameters() {
+::sw::mark::IFieldmark::parameter_map_t& WW8FieldEntry::getParameters() {
     return maParams;
@@ -1020,7 +1020,7 @@ long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes)
     bool bCodeNest = aF.bCodeNest;
     if ( aF.nId == 6 ) bCodeNest = false; // We can handle them and loose the inner data
-    maFieldStack.push_back(FieldEntry(*pPaM->GetPoint(), aF.nId));
+    maFieldStack.push_back(WW8FieldEntry(*pPaM->GetPoint(), aF.nId));
     if (bNested)
         return 0;

More information about the LibreOffice mailing list