sw/source/core/doc/DocumentRedlineManager.cxx | 9 ++++++++- sw/source/core/inc/ftnboss.hxx | 2 +- sw/source/core/layout/frmtool.cxx | 16 ++++++++++++---- sw/source/core/layout/ftnfrm.cxx | 6 +++++- sw/source/core/layout/wsfrm.cxx | 1 - sw/source/core/txtnode/atrftn.cxx | 8 ++++++-- 6 files changed, 32 insertions(+), 10 deletions(-)
New commits: commit a023327c17d809c8eef1ae5cc05a3f13f7069619 Author: Michael Stahl <[email protected]> AuthorDate: Mon Aug 6 19:03:22 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Aug 6 19:18:18 2018 +0200 sw: fix ignored frames in AppendAllObjs() The problem is that AppendAllObjs() doesn't check if MakeFrames() actually created frames, it just assumes success. If there are frames anchored in frames, then it could go through the circular_buffer, find a dependent frame before its anchor frame, unsuccessfully call MakeFrames(), then call MakeFrames() on the anchor frame, and then the vector is empty. A surprising aspect is that push_back on a boost::circular_buffer will silently pop the first element if it's already "full". Possibly this is what caused tdf#112447. 1. insert section 2. in paragraph in section, insert frame 3. repeat 2 4. drag anchor of frame 1 into body of frame 2 5. edit section, click hide 6. edit section, un-click hide 7. only one frame is displayed (regression from 575e222a1742918be052f2b716ddf57ce0008404 and/or ce2fce9a41729774689080c8b5552b60c2e6ee2d) Change-Id: Ie782252ac388524dfb083f655320a50e95239b24 diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index 2b59df47ee38..11cb79523ba7 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1223,9 +1223,11 @@ void AppendAllObjs(const SwFrameFormats* pTable, const SwFrame* pSib) if(!isConnected) { pFormat->MakeFrames(); - pFirstRequeued = nullptr; + pFormat->CallSwClientNotify(sw::GetObjectConnectedHint(isConnected, pRoot)); } - else + // do this *before* push_back! the circular_buffer can be "full"! + vFormatsToConnect.pop_front(); + if (!isConnected) { if(pFirstRequeued == pFormat) // If nothing happens anymore we can stop. @@ -1234,7 +1236,10 @@ void AppendAllObjs(const SwFrameFormats* pTable, const SwFrame* pSib) pFirstRequeued = pFormat; vFormatsToConnect.push_back(pFormat); } - vFormatsToConnect.pop_front(); + else + { + pFirstRequeued = nullptr; + } } } commit 60096c6f4e7199a9ddb3e1633edee8761073fc7e Author: Michael Stahl <[email protected]> AuthorDate: Mon Aug 6 14:39:25 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Aug 6 14:39:25 2018 +0200 assertion copypasta Change-Id: I7f114ca8df94c0489d0d75ce0bd0a485fdd36dc6 diff --git a/sw/source/core/layout/wsfrm.cxx b/sw/source/core/layout/wsfrm.cxx index e3684accaeae..aabcc91f1930 100644 --- a/sw/source/core/layout/wsfrm.cxx +++ b/sw/source/core/layout/wsfrm.cxx @@ -4392,7 +4392,6 @@ static void UnHideRedlinesExtras(SwRootFrame & rLayout, // note: SwStartNode has no way to access the frames, so check // whether the first content-node inside the section has frames SwNode const& rNode(*rNodes[j]); - assert(rNode.GetRedlineMergeFlag() == SwNode::Merge::None); if (rNode.IsSectionNode() && static_cast<SwSectionNode const&>(rNode).GetSection().IsHiddenFlag()) { // skip hidden sections - they can be inserted in fly-frames :( commit 509cf7e4e468fd67674e3c6a16069e0a13c0b983 Author: Michael Stahl <[email protected]> AuthorDate: Mon Aug 6 14:07:26 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Aug 6 14:07:26 2018 +0200 sw: fix return value of DocumentRedlineManager::AppendRedline() If a footnote is inserted, a redline that includes the start/end node of the footnote is created, but that is not a valid redline (as far as HasValidRange() is concerned), so instead a different redline without start/end nodes is inserted, but pNewRedl is reset and so AppendRedline() returns IGNORED, and then we get an assert in Undo from SwRedlineSaveData::RedlineToDoc(). Change-Id: I92253e1a40ba98e34e0bca601b4e3b6ef3751b08 diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 3b7a3a169c6b..6749614c36cf 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -1679,7 +1679,14 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall pNewRedl = nullptr; } else - mpRedlineTable->Insert( pNewRedl ); + { + bool const ret = mpRedlineTable->Insert( pNewRedl ); + assert(ret || !pNewRedl); + if (ret && !pNewRedl) + { + bMerged = true; // treat InsertWithValidRanges as "merge" + } + } } if( bCompress ) commit 39b850bb7833a37875a80ddc070e6a7d4d23a870 Author: Michael Stahl <[email protected]> AuthorDate: Mon Aug 6 13:31:37 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Aug 6 13:31:37 2018 +0200 sw_redlinehide_2: disable hiding at-char flys again Needs changes in Delete for consistency. Change-Id: If9382ebca9b6335ffef8c738840813837316f841 diff --git a/sw/source/core/layout/frmtool.cxx b/sw/source/core/layout/frmtool.cxx index 757af06f176a..2b59df47ee38 100644 --- a/sw/source/core/layout/frmtool.cxx +++ b/sw/source/core/layout/frmtool.cxx @@ -1043,7 +1043,10 @@ static bool IsShown(sal_uLong const nIndex, { return false; } - if (pIter && rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA) + if (pIter && rAnch.GetAnchorId() != RndStdIds::FLY_AT_PARA + // sw_redlinehide: we want to hide AT_CHAR, but currently can't + // because Delete and Accept Redline don't delete them! + && rAnch.GetAnchorId() != RndStdIds::FLY_AT_CHAR) { // note: frames are not sorted by anchor position. assert(pEnd); commit 3cfcc90e410dcea18b1d0ff77b3f951c956fce45 Author: Michael Stahl <[email protected]> AuthorDate: Mon Aug 6 12:42:27 2018 +0200 Commit: Michael Stahl <[email protected]> CommitDate: Mon Aug 6 12:42:27 2018 +0200 sw_redlinehide_2: fix use-after-free in SwFootnoteFrame On hide, the SwTextFootnote::DelFrames() for a note in a deleted frame must actually delete the frames; if there's a follow SwTextFrame, then it might erroneously return without deleting anything. Change-Id: I7e9473b94feaf939be72e285553a8990c2ce1a06 diff --git a/sw/source/core/inc/ftnboss.hxx b/sw/source/core/inc/ftnboss.hxx index a04c8ae172eb..ba363e53a2f7 100644 --- a/sw/source/core/inc/ftnboss.hxx +++ b/sw/source/core/inc/ftnboss.hxx @@ -75,7 +75,7 @@ public: // footnote interface void AppendFootnote( SwContentFrame *, SwTextFootnote * ); - void RemoveFootnote( const SwContentFrame *, const SwTextFootnote *, bool bPrep = true ); + bool RemoveFootnote(const SwContentFrame *, const SwTextFootnote *, bool bPrep = true); static SwFootnoteFrame *FindFootnote( const SwContentFrame *, const SwTextFootnote * ); SwFootnoteContFrame *FindFootnoteCont(); inline const SwFootnoteContFrame *FindFootnoteCont() const; diff --git a/sw/source/core/layout/ftnfrm.cxx b/sw/source/core/layout/ftnfrm.cxx index e34c2603d7bd..591b50dc4af8 100644 --- a/sw/source/core/layout/ftnfrm.cxx +++ b/sw/source/core/layout/ftnfrm.cxx @@ -1641,12 +1641,15 @@ SwFootnoteFrame *SwFootnoteBossFrame::FindFootnote( const SwContentFrame *pRef, return nullptr; } -void SwFootnoteBossFrame::RemoveFootnote( const SwContentFrame *pRef, const SwTextFootnote *pAttr, +bool SwFootnoteBossFrame::RemoveFootnote( + const SwContentFrame *const pRef, const SwTextFootnote *const pAttr, bool bPrep ) { + bool ret(false); SwFootnoteFrame *pFootnote = FindFootnote( pRef, pAttr ); if( pFootnote ) { + ret = true; do { SwFootnoteFrame *pFoll = pFootnote->GetFollow(); @@ -1663,6 +1666,7 @@ void SwFootnoteBossFrame::RemoveFootnote( const SwContentFrame *pRef, const SwTe } } FindPageFrame()->UpdateFootnoteNum(); + return ret; } void SwFootnoteBossFrame::ChangeFootnoteRef( const SwContentFrame *pOld, const SwTextFootnote *pAttr, diff --git a/sw/source/core/txtnode/atrftn.cxx b/sw/source/core/txtnode/atrftn.cxx index 26f41e0333eb..cc0e6f0ea12a 100644 --- a/sw/source/core/txtnode/atrftn.cxx +++ b/sw/source/core/txtnode/atrftn.cxx @@ -444,8 +444,12 @@ void SwTextFootnote::DelFrames( const SwFrame* pSib ) SwPageFrame* pPage = pFnd->FindPageFrame(); if( pPage ) { - pPage->RemoveFootnote( pFnd, this ); - bFrameFnd = true; + // note: we have found the correct frame only if the footnote + // was actually removed; in case this is called from + // SwTextFrame::DestroyImpl(), then that frame isn't connected + // to SwPageFrame any more, and RemoveFootnote on any follow + // must not prevent the fall-back to the !bFrameFnd code. + bFrameFnd = pPage->RemoveFootnote(pFnd, this); } } } _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
