summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2017-09-15 13:51:04 +0200
committerCaolán McNamara <caolanm@redhat.com>2017-09-27 11:54:45 +0200
commit34905a6e9e0c262b61e5969274b661692af44a46 (patch)
tree02d850c2d7a22b76b25c475f99c5e08c1ac2b566 /sw
parent31baba076f6058d675588b2715a3322455c87500 (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.cxx69
-rw-r--r--sw/source/core/inc/DocumentRedlineManager.hxx1
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;
};
}