summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-10-03 23:04:41 +0200
committerCaolán McNamara <caolanm@redhat.com>2022-10-05 09:54:48 +0200
commit6bbb7140c938d8f494ce75be5b5c7a3ae440ca87 (patch)
tree83fb6ec92f984859e6cafd84436cce8034459887
parentrhbz#2122948 sw: fix ODF import of fieldmark in redline (diff)
downloadcore-6bbb7140c938d8f494ce75be5b5c7a3ae440ca87.tar.gz
core-6bbb7140c938d8f494ce75be5b5c7a3ae440ca87.zip
tdf#151094 ODT export: fix crash when linked paragraph style is deleted
If a document contains a linked paragraph-character style pair and the paragraph style gets deleted, we crash on save. Commit 3227975c0f42ff23d528f5ab94b4538c8af764c (sw: paragraph styles: add doc model & UNO API for a linked character style, 2021-09-24) added support for linked para/char styles, but it failed to get the lifecycle correctly when it comes to deleting these styles. Fix the dangling para/char style references by explicitly looking what styles may refer to us and clear their references. An alternative would be to clear the "link" pointer of our own "link" pointer only, but broken documents may e.g. link multiple paragraph styles to a single character style, so this is probably not enough. Change-Id: I9465d43e90cf54c3c02bffda3e7c75b52c543a65 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140930 Tested-by: Jenkins Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140937 (cherry picked from commit 7746f532a1e89bb946b40b5c111acc27e78ab812) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/140955 Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--sw/inc/charfmt.hxx3
-rw-r--r--sw/inc/fmtcol.hxx2
-rw-r--r--sw/qa/core/doc/doc.cxx30
-rw-r--r--sw/source/core/doc/fmtcol.cxx15
-rw-r--r--sw/source/core/txtnode/chrfmt.cxx19
-rw-r--r--sw/source/uibase/app/docstyle.cxx4
6 files changed, 67 insertions, 6 deletions
diff --git a/sw/inc/charfmt.hxx b/sw/inc/charfmt.hxx
index e08d2f5f3a3f..84571d26263a 100644
--- a/sw/inc/charfmt.hxx
+++ b/sw/inc/charfmt.hxx
@@ -36,10 +36,11 @@ class SW_DLLPUBLIC SwCharFormat final : public SwFormat
{}
public:
+ ~SwCharFormat();
void dumpAsXml(xmlTextWriterPtr pWriter) const;
- void SetLinkedParaFormat(SwTextFormatColl& rLink);
+ void SetLinkedParaFormat(SwTextFormatColl* pLink);
const SwTextFormatColl* GetLinkedParaFormat() const;
};
diff --git a/sw/inc/fmtcol.hxx b/sw/inc/fmtcol.hxx
index 1b1bd7d2e46d..be547df3d840 100644
--- a/sw/inc/fmtcol.hxx
+++ b/sw/inc/fmtcol.hxx
@@ -103,7 +103,7 @@ public:
inline void SetNextTextFormatColl(SwTextFormatColl& rNext);
SwTextFormatColl& GetNextTextFormatColl() const { return *mpNextTextFormatColl; }
- void SetLinkedCharFormat(SwCharFormat& rLink);
+ void SetLinkedCharFormat(SwCharFormat* pLink);
const SwCharFormat* GetLinkedCharFormat() const;
diff --git a/sw/qa/core/doc/doc.cxx b/sw/qa/core/doc/doc.cxx
index 520041f44562..c13e7a8d6a55 100644
--- a/sw/qa/core/doc/doc.cxx
+++ b/sw/qa/core/doc/doc.cxx
@@ -19,6 +19,7 @@
#include <sfx2/viewfrm.hxx>
#include <sfx2/dispatch.hxx>
#include <vcl/scheduler.hxx>
+#include <comphelper/propertyvalue.hxx>
#include <wrtsh.hxx>
#include <fmtanchr.hxx>
@@ -255,6 +256,35 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testContentControlDelete)
CPPUNIT_ASSERT_EQUAL(OUString("\x0001test\x0001"), pTextNode->GetText());
}
+CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testLinkedStyleDelete)
+{
+ // Given a document with linked styles: myparastyle is linked to mycharstyle and vica versa:
+ createSwDoc();
+ uno::Reference<lang::XMultiServiceFactory> xFactory(mxComponent, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xParaStyle(
+ xFactory->createInstance("com.sun.star.style.ParagraphStyle"), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCharStyle(
+ xFactory->createInstance("com.sun.star.style.CharacterStyle"), uno::UNO_QUERY);
+ uno::Reference<container::XNameContainer> xParaStyles(getStyles("ParagraphStyles"),
+ uno::UNO_QUERY);
+ xParaStyles->insertByName("myparastyle", uno::Any(xParaStyle));
+ uno::Reference<container::XNameContainer> xCharStyles(getStyles("CharacterStyles"),
+ uno::UNO_QUERY);
+ xCharStyles->insertByName("mycharstyle", uno::Any(xCharStyle));
+ xParaStyle->setPropertyValue("LinkStyle", uno::Any(OUString("mycharstyle")));
+ xCharStyle->setPropertyValue("LinkStyle", uno::Any(OUString("myparastyle")));
+
+ // When deleting the paragraph style (and only that):
+ xParaStyles->removeByName("myparastyle");
+
+ // Then make sure we don't crash on save:
+ uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
+ uno::Sequence<beans::PropertyValue> aArgs = {
+ comphelper::makePropertyValue("FilterName", OUString("writer8")),
+ };
+ xStorable->storeAsURL(maTempFile.GetURL(), aArgs);
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/fmtcol.cxx b/sw/source/core/doc/fmtcol.cxx
index 9cc951b52a0c..e020aab191f4 100644
--- a/sw/source/core/doc/fmtcol.cxx
+++ b/sw/source/core/doc/fmtcol.cxx
@@ -113,6 +113,19 @@ SwTextFormatColl::~SwTextFormatColl()
{
if(m_bInSwFntCache)
pSwFontCache->Delete( this );
+
+ if (GetDoc()->IsInDtor())
+ {
+ return;
+ }
+
+ for (const auto& pCharFormat : *GetDoc()->GetCharFormats())
+ {
+ if (pCharFormat->GetLinkedParaFormat() == this)
+ {
+ pCharFormat->SetLinkedParaFormat(nullptr);
+ }
+ }
}
void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rHint)
{
@@ -316,7 +329,7 @@ void SwTextFormatColl::SwClientNotify(const SwModify& rModify, const SfxHint& rH
SwFormatColl::SwClientNotify(rModify, rHint);
}
-void SwTextFormatColl::SetLinkedCharFormat(SwCharFormat& rLink) { mpLinkedCharFormat = &rLink; }
+void SwTextFormatColl::SetLinkedCharFormat(SwCharFormat* pLink) { mpLinkedCharFormat = pLink; }
const SwCharFormat* SwTextFormatColl::GetLinkedCharFormat() const { return mpLinkedCharFormat; }
diff --git a/sw/source/core/txtnode/chrfmt.cxx b/sw/source/core/txtnode/chrfmt.cxx
index d2e01640071d..11a89d6eb92d 100644
--- a/sw/source/core/txtnode/chrfmt.cxx
+++ b/sw/source/core/txtnode/chrfmt.cxx
@@ -21,6 +21,7 @@
#include <charfmt.hxx>
#include <charformats.hxx>
+#include <doc.hxx>
void SwCharFormat::dumpAsXml(xmlTextWriterPtr pWriter) const
{
@@ -38,10 +39,26 @@ void SwCharFormat::dumpAsXml(xmlTextWriterPtr pWriter) const
(void)xmlTextWriterEndElement(pWriter);
}
-void SwCharFormat::SetLinkedParaFormat(SwTextFormatColl& rLink) { mpLinkedParaFormat = &rLink; }
+void SwCharFormat::SetLinkedParaFormat(SwTextFormatColl* pLink) { mpLinkedParaFormat = pLink; }
const SwTextFormatColl* SwCharFormat::GetLinkedParaFormat() const { return mpLinkedParaFormat; }
+SwCharFormat::~SwCharFormat()
+{
+ if (GetDoc()->IsInDtor())
+ {
+ return;
+ }
+
+ for (const auto& pTextFormat : *GetDoc()->GetTextFormatColls())
+ {
+ if (pTextFormat->GetLinkedCharFormat() == this)
+ {
+ pTextFormat->SetLinkedCharFormat(nullptr);
+ }
+ }
+}
+
void SwCharFormats::dumpAsXml(xmlTextWriterPtr pWriter) const
{
(void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwCharFormats"));
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index fa53a595f2fd..25c5c122592a 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -744,7 +744,7 @@ void SwDocStyleSheet::SetLink(const OUString& rStr)
SwCharFormat* pLink = lcl_FindCharFormat(m_rDoc, rStr);
if (pLink)
{
- m_pColl->SetLinkedCharFormat(*pLink);
+ m_pColl->SetLinkedCharFormat(pLink);
}
}
break;
@@ -756,7 +756,7 @@ void SwDocStyleSheet::SetLink(const OUString& rStr)
SwTextFormatColl* pLink = lcl_FindParaFormat(m_rDoc, rStr);
if (pLink)
{
- m_pCharFormat->SetLinkedParaFormat(*pLink);
+ m_pCharFormat->SetLinkedParaFormat(pLink);
}
}
break;