editeng/qa/editeng/editeng.cxx      |   33 +++++++++++++++++++++++++++++++++
 editeng/source/editeng/impedit4.cxx |   20 +++++++++++++++-----
 2 files changed, 48 insertions(+), 5 deletions(-)

New commits:
commit 65e3b433b3e53e3fa308b0ba66eb8c38670eda8f
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Dec 18 10:36:48 2024 +0100
Commit:     Aron Budea <aron.bu...@collabora.com>
CommitDate: Mon Jan 6 10:16:24 2025 +0100

    Related: tdf#164359 editeng RTF export: track unused follow styles 
recursively
    
    Similar to commit a7a81b6fbe37af938ce461e790fac517be032317 (tdf#164359
    editeng RTF export: track unused parent styles recursively, 2024-12-18),
    the follows of a style has to be tracked recursively as well, to avoid a
    crash.
    
    The Impress UI doesn't seem to have a way to specify the parent/next
    name of a style, but you can definitely create such a follow chain from
    test code and probably this is also possible via macros.
    
    Fix this similar to the parent case, except here handle when a style
    sets itself as a follow: that's what the default Outline N styles do in
    Impress.
    
    Change-Id: If3847add02061fdb9ba1e3fbf7c1fc42e3866209
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178786
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 65043a50adf8d56e1f965ec48b9609ca836ccced)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/178816
    Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com>
    (cherry picked from commit 8e662d6878a3e38eb79ec01113984cc01df72ea5)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179815
    Reviewed-by: Aron Budea <aron.bu...@collabora.com>

diff --git a/editeng/qa/editeng/editeng.cxx b/editeng/qa/editeng/editeng.cxx
index 7358bca5dd59..f3df37592f14 100644
--- a/editeng/qa/editeng/editeng.cxx
+++ b/editeng/qa/editeng/editeng.cxx
@@ -157,6 +157,39 @@ CPPUNIT_TEST_FIXTURE(Test, 
testRTFStyleExportParentRecursive)
     SvMemoryStream& rStream = pData->GetRTFStream();
     CPPUNIT_ASSERT_GREATER(static_cast<sal_uInt64>(0), 
rStream.remainingSize());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testRTFStyleExportFollowRecursive)
+{
+    // Given a document with text that has a paragraph style with a follow 
that itself has a follow:
+    EditEngine aEditEngine(mpItemPool.get());
+    rtl::Reference<SfxStyleSheetPool> xStyles(new 
SfxStyleSheetPool(*mpItemPool));
+    xStyles->Make("mystyle1", SfxStyleFamily::Para);
+    xStyles->Make("mystyle2", SfxStyleFamily::Para);
+    xStyles->Make("mystyle3", SfxStyleFamily::Para);
+    auto pStyle1 = static_cast<SfxStyleSheet*>(xStyles->Find("mystyle1", 
SfxStyleFamily::Para));
+    auto pStyle2 = static_cast<SfxStyleSheet*>(xStyles->Find("mystyle2", 
SfxStyleFamily::Para));
+    auto pStyle3 = static_cast<SfxStyleSheet*>(xStyles->Find("mystyle3", 
SfxStyleFamily::Para));
+    pStyle1->SetFollow(pStyle2->GetName());
+    pStyle2->SetFollow(pStyle3->GetName());
+    pStyle3->SetFollow(pStyle3->GetName());
+    pStyle1->GetItemSet().SetRanges(svl::Items<WEIGHT_BOLD, EE_CHAR_WEIGHT>);
+    SvxWeightItem aItem(WEIGHT_BOLD, EE_CHAR_WEIGHT);
+    pStyle1->GetItemSet().Put(aItem);
+    aEditEngine.SetStyleSheetPool(xStyles.get());
+    OUString aText = u"mytest"_ustr;
+    aEditEngine.SetText(aText);
+    aEditEngine.SetStyleSheet(0, pStyle1);
+
+    // When copying to the clipboard as RTF:
+    // Without the accompanying fix in place, this test would have crashed 
here:
+    uno::Reference<datatransfer::XTransferable> xData
+        = aEditEngine.CreateTransferable(ESelection(0, 0, 0, 
aText.getLength()));
+
+    // Then make sure we produce RTF and not crash:
+    auto pData = dynamic_cast<EditDataObject*>(xData.get());
+    SvMemoryStream& rStream = pData->GetRTFStream();
+    CPPUNIT_ASSERT_GREATER(static_cast<sal_uInt64>(0), 
rStream.remainingSize());
+}
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/editeng/source/editeng/impedit4.cxx 
b/editeng/source/editeng/impedit4.cxx
index 6f1cf6abeb2b..cf49099bd6e0 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -468,15 +468,25 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, 
EditSelection aSel, bool bCl
                     aParent = pParent->GetParent();
                 }
 
-                const OUString& rFollow = pParaStyle->GetFollow();
-                if (!rFollow.isEmpty())
+                // Collect follows of the style recursively.
+                OUString aFollow = pParaStyle->GetFollow();
+                while (!aFollow.isEmpty())
                 {
                     auto pFollow = static_cast<SfxStyleSheet*>(
-                        GetStyleSheetPool()->Find(rFollow, 
pParaStyle->GetFamily()));
-                    if (pFollow)
+                        GetStyleSheetPool()->Find(aFollow, 
pParaStyle->GetFamily()));
+                    if (!pFollow)
                     {
-                        aUsedParagraphStyles.insert(pFollow);
+                        break;
+                    }
+
+                    auto it = aUsedParagraphStyles.insert(pFollow);
+                    // A style is fine to have itself as a follow.
+                    if (!it.second)
+                    {
+                        // No insertion happened, so this is visited already.
+                        break;
                     }
+                    aFollow = pFollow->GetFollow();
                 }
             }
         }

Reply via email to