sw/source/core/doc/docdesc.cxx |  132 ++++++++++++++++++++++-------------------
 1 file changed, 72 insertions(+), 60 deletions(-)

New commits:
commit 89b0d94850aeda0a97907945538e4d5f41bac970
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Wed Jun 1 12:02:36 2022 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Jun 1 14:18:47 2022 +0200

    sw: fix crash in SwDoc::CopyMasterHeader and SwDoc::CopyMasterFooter
    
    Similar to 3eda5d345f14f8926358df7b425c452a8a165c7d
    "tdf#149184 DOCX: fix crash removing footer, then saving to doc"
    check that GetHeaderFormat and GetFooterFormat are not nullptr
    Also restructure the code a bit to reduce the scope of pRight
    
    See 
https://crashreport.libreoffice.org/stats/signature/SwDoc::CopyMasterHeader(SwPageDesc%20const%20&,SwFormatHeader%20const%20&,SwPageDesc%20&,bool,bool)
    and
    
https://crashreport.libreoffice.org/stats/signature/SwDoc::CopyMasterFooter(SwPageDesc%20const%20&,SwFormatFooter%20const%20&,SwPageDesc%20&,bool,bool)
    
    Change-Id: Ia30d06593124d90b88f7d26ed7be9a5d7a64872c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135230
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/source/core/doc/docdesc.cxx b/sw/source/core/doc/docdesc.cxx
index d22fee74ca79..1ba9d86b480f 100644
--- a/sw/source/core/doc/docdesc.cxx
+++ b/sw/source/core/doc/docdesc.cxx
@@ -268,8 +268,6 @@ void SwDoc::CopyMasterHeader(const SwPageDesc &rChged, 
const SwFormatHeader &rHe
         }
         else
         {
-            const SwFrameFormat *pRight = rHead.GetHeaderFormat();
-            const SwFormatContent &aRCnt = pRight->GetContent();
             const SwFormatContent &aCnt = 
rFormatHead.GetHeaderFormat()->GetContent();
 
             if (!aCnt.GetContentIdx())
@@ -277,36 +275,44 @@ void SwDoc::CopyMasterHeader(const SwPageDesc &rChged, 
const SwFormatHeader &rHe
                 const SwFrameFormat& rChgedFrameFormat = 
getConstFrameFormat(rChged, bLeft, bFirst);
                 rDescFrameFormat.SetFormatAttr( rChgedFrameFormat.GetHeader() 
);
             }
-            else if ((*aRCnt.GetContentIdx() == *aCnt.GetContentIdx()) ||
-                // The ContentIdx is _always_ different when called from
-                // SwDocStyleSheet::SetItemSet, because it deep-copies the
-                // PageDesc.  So check if it was previously shared.
-                 (bFirst ? rDesc.IsFirstShared() : rDesc.IsHeaderShared()))
+            else
             {
-                SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(),
-                        bFirst ? "First header" : "Left header",
-                                                GetDfltFrameFormat() );
-                ::lcl_DescSetAttr( *pRight, *pFormat, false );
-                // The section which the right header attribute is pointing
-                // is copied, and the Index to the StartNode is set to
-                // the left or first header attribute.
-                SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
-                SwStartNode* pSttNd = SwNodes::MakeEmptySection( aTmp, 
SwHeaderStartNode );
-                SwNodeRange aRange( aRCnt.GetContentIdx()->GetNode(), 
SwNodeOffset(0),
-                            
*aRCnt.GetContentIdx()->GetNode().EndOfSectionNode() );
-                aTmp = *pSttNd->EndOfSectionNode();
-                GetNodes().Copy_( aRange, aTmp, false );
-                aTmp = *pSttNd;
-                GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, 
nullptr, aTmp);
-                SwPaM const source(aRange.aStart, aRange.aEnd);
-                SwPosition dest(aTmp);
-                sw::CopyBookmarks(source, dest);
-                pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
-                rDescFrameFormat.SetFormatAttr( SwFormatHeader( pFormat ) );
+                const SwFrameFormat *pRight = rHead.GetHeaderFormat();
+                if (!pRight)
+                    return;
+                const SwFormatContent &aRCnt = pRight->GetContent();
+
+                if ((*aRCnt.GetContentIdx() == *aCnt.GetContentIdx()) ||
+                    // The ContentIdx is _always_ different when called from
+                    // SwDocStyleSheet::SetItemSet, because it deep-copies the
+                    // PageDesc.  So check if it was previously shared.
+                     (bFirst ? rDesc.IsFirstShared() : rDesc.IsHeaderShared()))
+                {
+                    SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(),
+                            bFirst ? "First header" : "Left header",
+                                                    GetDfltFrameFormat() );
+                    ::lcl_DescSetAttr( *pRight, *pFormat, false );
+                    // The section which the right header attribute is pointing
+                    // is copied, and the Index to the StartNode is set to
+                    // the left or first header attribute.
+                    SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
+                    SwStartNode* pSttNd = SwNodes::MakeEmptySection( aTmp, 
SwHeaderStartNode );
+                    SwNodeRange aRange( aRCnt.GetContentIdx()->GetNode(), 
SwNodeOffset(0),
+                                
*aRCnt.GetContentIdx()->GetNode().EndOfSectionNode() );
+                    aTmp = *pSttNd->EndOfSectionNode();
+                    GetNodes().Copy_( aRange, aTmp, false );
+                    aTmp = *pSttNd;
+                    
GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, nullptr, aTmp);
+                    SwPaM const source(aRange.aStart, aRange.aEnd);
+                    SwPosition dest(aTmp);
+                    sw::CopyBookmarks(source, dest);
+                    pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
+                    rDescFrameFormat.SetFormatAttr( SwFormatHeader( pFormat ) 
);
+                }
+                else
+                    ::lcl_DescSetAttr( *pRight,
+                                   
*const_cast<SwFrameFormat*>(rFormatHead.GetHeaderFormat()), false );
             }
-            else
-                ::lcl_DescSetAttr( *pRight,
-                               
*const_cast<SwFrameFormat*>(rFormatHead.GetHeaderFormat()), false );
         }
     }
 }
@@ -343,44 +349,50 @@ void SwDoc::CopyMasterFooter(const SwPageDesc &rChged, 
const SwFormatFooter &rFo
         }
         else
         {
-            const SwFrameFormat *pRight = rFoot.GetFooterFormat();
-            const SwFormatContent &aRCnt = pRight->GetContent();
             const SwFormatContent &aLCnt = 
rFormatFoot.GetFooterFormat()->GetContent();
             if( !aLCnt.GetContentIdx() )
             {
                 const SwFrameFormat& rChgedFrameFormat = 
getConstFrameFormat(rChged, bLeft, bFirst);
                 rDescFrameFormat.SetFormatAttr( rChgedFrameFormat.GetFooter() 
);
             }
-            else if ((*aRCnt.GetContentIdx() == *aLCnt.GetContentIdx()) ||
-                // The ContentIdx is _always_ different when called from
-                // SwDocStyleSheet::SetItemSet, because it deep-copies the
-                // PageDesc.  So check if it was previously shared.
-                 (bFirst ? rDesc.IsFirstShared() : rDesc.IsFooterShared()))
+            else
             {
-                SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(),
-                        bFirst ? "First footer" : "Left footer",
-                                                GetDfltFrameFormat() );
-                ::lcl_DescSetAttr( *pRight, *pFormat, false );
-                // The section to which the right footer attribute is pointing
-                // is copied, and the Index to the StartNode is set to
-                // the left footer attribute.
-                SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
-                SwStartNode* pSttNd = SwNodes::MakeEmptySection( aTmp, 
SwFooterStartNode );
-                SwNodeRange aRange( aRCnt.GetContentIdx()->GetNode(), 
SwNodeOffset(0),
-                            
*aRCnt.GetContentIdx()->GetNode().EndOfSectionNode() );
-                aTmp = *pSttNd->EndOfSectionNode();
-                GetNodes().Copy_( aRange, aTmp, false );
-                aTmp = *pSttNd;
-                GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, 
nullptr, aTmp);
-                SwPaM const source(aRange.aStart, aRange.aEnd);
-                SwPosition dest(aTmp);
-                sw::CopyBookmarks(source, dest);
-                pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
-                rDescFrameFormat.SetFormatAttr( SwFormatFooter( pFormat ) );
+                const SwFrameFormat *pRight = rFoot.GetFooterFormat();
+                if (!pRight)
+                    return;
+                const SwFormatContent &aRCnt = pRight->GetContent();
+
+                if ((*aRCnt.GetContentIdx() == *aLCnt.GetContentIdx()) ||
+                    // The ContentIdx is _always_ different when called from
+                    // SwDocStyleSheet::SetItemSet, because it deep-copies the
+                    // PageDesc.  So check if it was previously shared.
+                     (bFirst ? rDesc.IsFirstShared() : rDesc.IsFooterShared()))
+                {
+                    SwFrameFormat *pFormat = new SwFrameFormat( GetAttrPool(),
+                            bFirst ? "First footer" : "Left footer",
+                                                    GetDfltFrameFormat() );
+                    ::lcl_DescSetAttr( *pRight, *pFormat, false );
+                    // The section to which the right footer attribute is 
pointing
+                    // is copied, and the Index to the StartNode is set to
+                    // the left footer attribute.
+                    SwNodeIndex aTmp( GetNodes().GetEndOfAutotext() );
+                    SwStartNode* pSttNd = SwNodes::MakeEmptySection( aTmp, 
SwFooterStartNode );
+                    SwNodeRange aRange( aRCnt.GetContentIdx()->GetNode(), 
SwNodeOffset(0),
+                                
*aRCnt.GetContentIdx()->GetNode().EndOfSectionNode() );
+                    aTmp = *pSttNd->EndOfSectionNode();
+                    GetNodes().Copy_( aRange, aTmp, false );
+                    aTmp = *pSttNd;
+                    
GetDocumentContentOperationsManager().CopyFlyInFlyImpl(aRange, nullptr, aTmp);
+                    SwPaM const source(aRange.aStart, aRange.aEnd);
+                    SwPosition dest(aTmp);
+                    sw::CopyBookmarks(source, dest);
+                    pFormat->SetFormatAttr( SwFormatContent( pSttNd ) );
+                    rDescFrameFormat.SetFormatAttr( SwFormatFooter( pFormat ) 
);
+                }
+                else
+                    ::lcl_DescSetAttr( *pRight,
+                                   
*const_cast<SwFrameFormat*>(rFormatFoot.GetFooterFormat()), false );
             }
-            else
-                ::lcl_DescSetAttr( *pRight,
-                               
*const_cast<SwFrameFormat*>(rFormatFoot.GetFooterFormat()), false );
         }
     }
 }

Reply via email to