diff options
author | Xisco Fauli <xiscofauli@libreoffice.org> | 2022-06-01 12:02:36 +0200 |
---|---|---|
committer | Andras Timar <andras.timar@collabora.com> | 2022-06-09 11:00:57 +0200 |
commit | ac3969aaf5b57d0d0834fabb43430fbd1c1d13ef (patch) | |
tree | 3d688d804fef04842e82545c73658a4e7b5d37be /sw | |
parent | c3df2d673cc12baa1f851510348a785d3e4566fa (diff) |
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 <vmiklos@collabora.com>
Tested-by: Jenkins
(cherry picked from commit 89b0d94850aeda0a97907945538e4d5f41bac970)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135256
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/doc/docdesc.cxx | 132 |
1 files changed, 72 insertions, 60 deletions
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 ); } } } |