diff options
author | Michael Stahl <mstahl@redhat.com> | 2017-09-15 13:51:04 +0200 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-09-27 11:54:45 +0200 |
commit | 34905a6e9e0c262b61e5969274b661692af44a46 (patch) | |
tree | 02d850c2d7a22b76b25c475f99c5e08c1ac2b566 /sw | |
parent | 31baba076f6058d675588b2715a3322455c87500 (diff) |
ofz#3301 sw: DeleteAndJoin found yet another way to delete new redline
Not only can that happen in CompressRedlines(), it can also happen
in the SwComparePosition::Outside case when the DeleteRedline()
decides in particular circumstances to split up the inserted
new redline.
Arguably it's wrong to split up the new redline in this case;
not sure if that ever happens in a legitimate use case though.
Avoid this by removing the hack to temporarily insert the new redline
and instead create a temporary SwUnoCursor that will be corrected
on behalf of the new redline, while the new redline is parked on a
safe node.
This not only avoids the crash on this file but also makes the
"corrupted redline table" assertions go away.
Change-Id: I478f4cfc53a19d2cf2f0937f631962f80b1815ff
Reviewed-on: https://gerrit.libreoffice.org/42322
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/core/doc/DocumentRedlineManager.cxx | 69 | ||||
-rw-r--r-- | sw/source/core/inc/DocumentRedlineManager.hxx | 1 |
2 files changed, 31 insertions, 39 deletions
diff --git a/sw/source/core/doc/DocumentRedlineManager.cxx b/sw/source/core/doc/DocumentRedlineManager.cxx index 1d9a24be3153..92557481bd8d 100644 --- a/sw/source/core/doc/DocumentRedlineManager.cxx +++ b/sw/source/core/doc/DocumentRedlineManager.cxx @@ -25,6 +25,7 @@ #include <UndoRedline.hxx> #include <docary.hxx> #include <ndtxt.hxx> +#include <unocrsr.hxx> #include <strings.hrc> #include <swmodule.hxx> #include <editsh.hxx> @@ -574,6 +575,32 @@ namespace } } } + + /// in case some text is deleted, ensure that the not-yet-inserted + /// SwRangeRedline has its positions corrected not to point to deleted node + class TemporaryRedlineUpdater + { + private: + SwRangeRedline & m_rRedline; + std::shared_ptr<SwUnoCursor> m_pCursor; + public: + TemporaryRedlineUpdater(SwDoc & rDoc, SwRangeRedline & rRedline) + : m_rRedline(rRedline) + , m_pCursor(rDoc.CreateUnoCursor(*rRedline.GetPoint(), false)) + { + if (m_rRedline.HasMark()) + { + m_pCursor->SetMark(); + *m_pCursor->GetMark() = *m_rRedline.GetMark(); + *m_rRedline.GetMark() = SwPosition(rDoc.GetNodes().GetEndOfContent()); + } + *m_rRedline.GetPoint() = SwPosition(rDoc.GetNodes().GetEndOfContent()); + } + ~TemporaryRedlineUpdater() + { + static_cast<SwPaM&>(m_rRedline) = *m_pCursor; + } + }; } namespace sw @@ -1228,20 +1255,11 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall { mpRedlineTable->Remove( n ); bDec = true; - // We insert temporarily so that pNew is - // also dealt with when moving the indices. if( bCallDelete ) { - ::comphelper::FlagGuard g(m_isForbidCompressRedlines); - //Insert may delete pNewRedl, in which case it sets pNewRedl to nullptr - mpRedlineTable->Insert( pNewRedl ); + TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl); m_rDoc.getIDocumentContentOperations().DeleteAndJoin( *pRedl ); - if (pNewRedl && !mpRedlineTable->Remove(pNewRedl)) - { - assert(false); // can't happen - pNewRedl = nullptr; - } - bCompress = true; // delayed compress + n = 0; // re-initialize } delete pRedl; } @@ -1263,18 +1281,8 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall if( bCallDelete ) { - // We insert temporarily so that pNew is - // also dealt with when moving the indices. - ::comphelper::FlagGuard g(m_isForbidCompressRedlines); - //Insert may delete pNewRedl, in which case it sets pNewRedl to nullptr - mpRedlineTable->Insert( pNewRedl ); + TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl); m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam ); - if (pNewRedl && !mpRedlineTable->Remove(pNewRedl)) - { - assert(false); // can't happen - pNewRedl = nullptr; - } - bCompress = true; // delayed compress n = 0; // re-initialize } bDec = true; @@ -1295,18 +1303,8 @@ DocumentRedlineManager::AppendRedline(SwRangeRedline* pNewRedl, bool const bCall if( bCallDelete ) { - // We insert temporarily so that pNew is - // also dealt with when moving the indices. - ::comphelper::FlagGuard g(m_isForbidCompressRedlines); - //Insert may delete pNewRedl, in which case it sets pNewRedl to nullptr - mpRedlineTable->Insert( pNewRedl ); + TemporaryRedlineUpdater const u(m_rDoc, *pNewRedl); m_rDoc.getIDocumentContentOperations().DeleteAndJoin( aPam ); - if (pNewRedl && !mpRedlineTable->Remove(pNewRedl)) - { - assert(false); // can't happen - pNewRedl = nullptr; - } - bCompress = true; // delayed compress n = 0; // re-initialize bDec = true; } @@ -1797,11 +1795,6 @@ bool DocumentRedlineManager::AppendTableCellRedline( SwTableCellRedline* pNewRed void DocumentRedlineManager::CompressRedlines() { - if (m_isForbidCompressRedlines) - { - return; - } - CHECK_REDLINE( *this ) void (SwRangeRedline::*pFnc)(sal_uInt16, size_t) = nullptr; diff --git a/sw/source/core/inc/DocumentRedlineManager.hxx b/sw/source/core/inc/DocumentRedlineManager.hxx index 9ba7e5bd7f1d..afe8d4090271 100644 --- a/sw/source/core/inc/DocumentRedlineManager.hxx +++ b/sw/source/core/inc/DocumentRedlineManager.hxx @@ -138,7 +138,6 @@ private: sal_uInt16 mnAutoFormatRedlnCommentNo; /**< SeqNo for conjoining of AutoFormat-Redlines. by the UI. Managed by SwAutoFormat! */ css::uno::Sequence <sal_Int8 > maRedlinePasswd; - bool m_isForbidCompressRedlines = false; }; } |