sw/qa/core/layout/data/floattable-in-section.docx |binary
 sw/qa/core/layout/flycnt.cxx                      |    6 ++++
 sw/source/core/layout/fly.cxx                     |   32 ++++++++--------------
 3 files changed, 19 insertions(+), 19 deletions(-)

New commits:
commit ff28af2320da3da5e0b00e9f527009cebf8bd69f
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Fri Apr 21 09:03:51 2023 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Apr 26 11:02:09 2023 +0200

    sw floattable, crashtesting: fix PDF export of forum-mso-de-117064.docx
    
    Converting the bugdoc to PDF crashed Writer layout since commit
    ce3308a926f036b87515b8cd97d2b197063dc77a (tdf#61594 sw floattable:
    import floating tables as split flys by default, 2023-04-12).
    
    What happened is that we hit a case in the SwTextFrameBreak ctor where
    the frame had the "is in section" bit set, but the frame wasn't actually
    in a section, so when looking up that parent section frame, we found
    nothing, and later code assumed that we always find something. This is
    fine, the root of the problem was that in the non-legacy case
    GetFlyAnchorBottom() assumed the upper of the anchor frame is the body
    frame, so in case you had a protected section in DOCX, we mapped that
    into a Writer section, resulting in a body -> section -> anchor frame
    hierarchy.
    
    Fix the problem by improving GetFlyAnchorBottom(), so it works with the
    body frame of the page (of the anchor), not with the anchor's upper,
    which breaks in the section case.
    
    This only happened in the compatibilityMode=15 case, i.e. DOCX files
    produced by Word >= 2013.
    
    (cherry picked from commit a1c5f77d3ee7c9907c8247aa0e896e07fe9427b6)
    
    Change-Id: I94ed22701d275e7a9048c6154652d40268850c34
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150902
    Tested-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/core/layout/data/floattable-in-section.docx 
b/sw/qa/core/layout/data/floattable-in-section.docx
new file mode 100644
index 000000000000..a0e9090bcccf
Binary files /dev/null and b/sw/qa/core/layout/data/floattable-in-section.docx 
differ
diff --git a/sw/qa/core/layout/flycnt.cxx b/sw/qa/core/layout/flycnt.cxx
index 74368f01a01c..4a8578f58524 100644
--- a/sw/qa/core/layout/flycnt.cxx
+++ b/sw/qa/core/layout/flycnt.cxx
@@ -675,6 +675,12 @@ CPPUNIT_TEST_FIXTURE(Test, testSplitFly2ndRowSelect)
     // i.e. a follow fly was possible to select (instead of its master)
     CPPUNIT_ASSERT_EQUAL(pPage2Fly->GetPrecede()->GetFrameId(), 
pSelected->GetFrameId());
 }
+
+CPPUNIT_TEST_FIXTURE(Test, testSplitFlyInSection)
+{
+    // This crashed, the layout assumed that the floating table is directly 
under the body frame.
+    createSwDoc("floattable-in-section.docx");
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/fly.cxx b/sw/source/core/layout/fly.cxx
index e06483be8653..a8fef2394b1f 100644
--- a/sw/source/core/layout/fly.cxx
+++ b/sw/source/core/layout/fly.cxx
@@ -86,24 +86,24 @@ SwTwips GetFlyAnchorBottom(SwFlyFrame* pFly, const SwFrame& 
rAnchor)
 {
     SwRectFnSet aRectFnSet(pFly);
 
+    const SwPageFrame* pPage = rAnchor.FindPageFrame();
+    if (!pPage)
+    {
+        return 0;
+    }
+
+    const SwFrame* pBody = pPage->FindBodyCont();
+    if (!pBody)
+    {
+        return 0;
+    }
+
     const IDocumentSettingAccess& rIDSA = 
pFly->GetFrameFormat().getIDocumentSettingAccess();
     bool bLegacy = rIDSA.get(DocumentSettingId::TAB_OVER_MARGIN);
     if (bLegacy)
     {
         // Word <= 2010 style: the fly can overlap with the bottom margin / 
footer area in case the
         // fly height fits the body height and the fly bottom fits the page.
-        const SwPageFrame* pPage = rAnchor.FindPageFrame();
-        if (!pPage)
-        {
-            return 0;
-        }
-
-        const SwFrame* pBody = pPage->FindBodyCont();
-        if (!pBody)
-        {
-            return 0;
-        }
-
         // See if the fly height would fit at least the page height, ignoring 
the vertical offset.
         SwTwips nFlyHeight = aRectFnSet.GetHeight(pFly->getFrameArea());
         SwTwips nPageHeight = aRectFnSet.GetHeight(pPage->getFramePrintArea());
@@ -124,13 +124,7 @@ SwTwips GetFlyAnchorBottom(SwFlyFrame* pFly, const 
SwFrame& rAnchor)
     }
 
     // Word >= 2013 style: the fly has to stay inside the body frame.
-    const SwFrame* pAnchorUpper = rAnchor.GetUpper();
-    if (!pAnchorUpper)
-    {
-        return 0;
-    }
-
-    return aRectFnSet.GetPrtBottom(*pAnchorUpper);
+    return aRectFnSet.GetPrtBottom(*pBody);
 }
 }
 

Reply via email to