[libreoffice/f21] make certain change-tracking odts not crash on deleting text
Caolán McNamara
caolanm at fedoraproject.org
Fri Jan 30 17:19:14 UTC 2015
commit 8eb5b7ac0f24d9af464bcc201e544f166eeb5993
Author: Caolán McNamara <caolanm at redhat.com>
Date: Fri Jan 30 17:19:01 2015 +0000
make certain change-tracking odts not crash on deleting text
...mentRedlineManager-SetRedlineMode-the-arr.patch | 414 ++++++++++++++++++++
libreoffice.spec | 4 +-
2 files changed, 417 insertions(+), 1 deletions(-)
---
diff --git a/0001-During-DocumentRedlineManager-SetRedlineMode-the-arr.patch b/0001-During-DocumentRedlineManager-SetRedlineMode-the-arr.patch
new file mode 100644
index 0000000..bbd9f86
--- /dev/null
+++ b/0001-During-DocumentRedlineManager-SetRedlineMode-the-arr.patch
@@ -0,0 +1,414 @@
+From f3974a01283674f016ebd564652964302b1ab1e8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm at redhat.com>
+Date: Fri, 30 Jan 2015 15:34:30 +0000
+Subject: [PATCH] During DocumentRedlineManager::SetRedlineMode the array
+ becomes unsorted
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+so GetPos cannot be used safely, so pass down the known index
+of the redline and propogate it everywhere the redline goes
+
+This reverts
+
+commit 36e158ce7a0effb130936ba4598a193102faa6a1
+Author: Caolán McNamara <caolanm at redhat.com>
+Date: Mon Jan 19 12:09:17 2015 +0000
+
+ if we change the keys we have to resort based on the new keys
+
+which tried to keep the table sorted, but thats no use because
+DocumentRedlineManager::SetRedlineMode loops over by index
+so sorting the table during the process busts that.
+
+Taking a copy of the entries and looping over that shows another
+gadzillion problems.
+
+So try this approach instead.
+
+I imagine it should be possible to calculate the correct
+current index of pRedl in DocumentRedlineManager::AppendRedline
+but for now assume that we are sorted correctly at that
+point and can use GetPos
+
+(cherry picked from commit a5a20187c3a5e5956492f932c49501f9547e4915)
+
+Conflicts:
+ sw/source/core/doc/DocumentRedlineManager.cxx
+ sw/source/core/doc/docredln.cxx
+ sw/source/core/undo/unredln.cxx
+
+Change-Id: If092dce185e3b36fd256db390132358cba155847
+---
+ sw/inc/docary.hxx | 1 +
+ sw/inc/redline.hxx | 12 +++---
+ sw/source/core/doc/docredln.cxx | 90 ++++++++++++++++++++---------------------
+ sw/source/core/undo/unredln.cxx | 2 +-
+ 4 files changed, 51 insertions(+), 54 deletions(-)
+
+diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
+index 94f8229..34f22ed 100644
+--- a/sw/inc/docary.hxx
++++ b/sw/inc/docary.hxx
+@@ -195,6 +195,7 @@ public:
+ using _SwRedlineTbl::size;
+ using _SwRedlineTbl::operator[];
+ using _SwRedlineTbl::empty;
++ using _SwRedlineTbl::Resort;
+ };
+
+ /// Table that holds 'extra' redlines, such as 'table row insert\delete', 'paragraph moves' etc...
+diff --git a/sw/inc/redline.hxx b/sw/inc/redline.hxx
+index ab1945b..b639063 100644
+--- a/sw/inc/redline.hxx
++++ b/sw/inc/redline.hxx
+@@ -190,8 +190,8 @@ class SW_DLLPUBLIC SwRangeRedline : public SwPaM
+
+ void MoveToSection();
+ void CopyToSection();
+- void DelCopyOfSection();
+- void MoveFromSection();
++ void DelCopyOfSection(size_t nMyPos);
++ void MoveFromSection(size_t nMyPos);
+
+ public:
+ SwRangeRedline( RedlineType_t eType, const SwPaM& rPam );
+@@ -263,10 +263,10 @@ public:
+ // hide the Del-Redlines via Copy and Delete.
+ // Otherwise at Move the attribution would be handled incorrectly.
+ // All other callers must always give 0.
+- void CallDisplayFunc( sal_uInt16 nLoop = 0 );
+- void Show( sal_uInt16 nLoop = 0 );
+- void Hide( sal_uInt16 nLoop = 0 );
+- void ShowOriginal( sal_uInt16 nLoop = 0 );
++ void CallDisplayFunc(sal_uInt16 nLoop, size_t nMyPos);
++ void Show(sal_uInt16 nLoop , size_t nMyPos);
++ void Hide(sal_uInt16 nLoop , size_t nMyPos);
++ void ShowOriginal(sal_uInt16 nLoop, size_t nMyPos);
+
+ /// Calculates the intersection with text node number nNdIdx.
+ void CalcStartEnd(sal_uLong nNdIdx, sal_Int32& rStart, sal_Int32& rEnd) const;
+diff --git a/sw/source/core/doc/docredln.cxx b/sw/source/core/doc/docredln.cxx
+index 8d3d704..fd2730e 100644
+--- a/sw/source/core/doc/docredln.cxx
++++ b/sw/source/core/doc/docredln.cxx
+@@ -157,7 +157,7 @@ void SwDoc::SetRedlineMode( RedlineMode_t eMode )
+ bool bSaveInXMLImportFlag = IsInXMLImport();
+ SetInXMLImport( false );
+ // and then hide/display everything
+- void (SwRangeRedline::*pFnc)( sal_uInt16 ) = 0;
++ void (SwRangeRedline::*pFnc)(sal_uInt16, size_t) = 0;
+
+ switch( nsRedlineMode_t::REDLINE_SHOW_MASK & eMode )
+ {
+@@ -179,10 +179,17 @@ void SwDoc::SetRedlineMode( RedlineMode_t eMode )
+
+ _CHECK_REDLINE( this )
+
+- if( pFnc )
+- for( sal_uInt16 nLoop = 1; nLoop <= 2; ++nLoop )
+- for( sal_uInt16 i = 0; i < mpRedlineTbl->size(); ++i )
+- ((*mpRedlineTbl)[ i ]->*pFnc)( nLoop );
++ if (pFnc)
++ {
++ for (sal_uInt16 nLoop = 1; nLoop <= 2; ++nLoop)
++ for (size_t i = 0; i < mpRedlineTbl->size(); ++i)
++ ((*mpRedlineTbl)[i]->*pFnc)(nLoop, i);
++
++ //SwRangeRedline::MoveFromSection routinely changes
++ //the keys that mpRedlineTbl is sorted by
++ mpRedlineTbl->Resort();
++ }
++
+ _CHECK_REDLINE( this )
+ SetInXMLImport( bSaveInXMLImportFlag );
+ }
+@@ -705,7 +712,7 @@ bool SwDoc::AppendRedline( SwRangeRedline* pNewRedl, bool bCallDelete )
+ // We insert temporarily so that pNew is
+ // also dealt with when moving the indices.
+ mpRedlineTbl->Insert( pNewRedl );
+- pRedl->Show();
++ pRedl->Show(0, mpRedlineTbl->GetPos(pRedl));
+ mpRedlineTbl->Remove( pNewRedl );
+ pRStt = pRedl->Start();
+ pREnd = pRedl->End();
+@@ -882,7 +889,7 @@ bool SwDoc::AppendRedline( SwRangeRedline* pNewRedl, bool bCallDelete )
+ pRedl->PushData( *pNewRedl );
+ delete pNewRedl, pNewRedl = 0;
+ if( IsHideChanges( meRedlineMode ))
+- pRedl->Hide();
++ pRedl->Hide(0, mpRedlineTbl->GetPos(pRedl));
+ bCompress = true;
+ }
+ break;
+@@ -946,7 +953,7 @@ bool SwDoc::AppendRedline( SwRangeRedline* pNewRedl, bool bCallDelete )
+ if( IsHideChanges( meRedlineMode ))
+ {
+ mpRedlineTbl->Insert( pNewRedl );
+- pRedl->Hide();
++ pRedl->Hide(0, mpRedlineTbl->GetPos(pRedl));
+ mpRedlineTbl->Remove( pNewRedl );
+ }
+ }
+@@ -974,7 +981,7 @@ bool SwDoc::AppendRedline( SwRangeRedline* pNewRedl, bool bCallDelete )
+ if( IsHideChanges( meRedlineMode ))
+ {
+ mpRedlineTbl->Insert( pNewRedl );
+- pRedl->Hide();
++ pRedl->Hide(0, mpRedlineTbl->GetPos(pRedl));
+ mpRedlineTbl->Remove( pNewRedl );
+ }
+ }
+@@ -1255,7 +1262,7 @@ void SwDoc::CompressRedlines()
+ {
+ _CHECK_REDLINE( this )
+
+- void (SwRangeRedline::*pFnc)(sal_uInt16) = 0;
++ void (SwRangeRedline::*pFnc)(sal_uInt16, size_t) = 0;
+ switch( nsRedlineMode_t::REDLINE_SHOW_MASK & meRedlineMode )
+ {
+ case nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE:
+@@ -1283,14 +1290,15 @@ void SwDoc::CompressRedlines()
+ !pCurEnd->nNode.GetNode().StartOfSectionNode()->IsTableNode() )
+ {
+ // we then can merge them
+- pPrev->Show();
+- pCur->Show();
++ size_t nPrevIndex = n-1;
++ pPrev->Show(0, nPrevIndex);
++ pCur->Show(0, n);
+
+ pPrev->SetEnd( *pCur->End() );
+ mpRedlineTbl->DeleteAndDestroy( n );
+ --n;
+ if( pFnc )
+- (pPrev->*pFnc)(0);
++ (pPrev->*pFnc)(0, nPrevIndex);
+ }
+ }
+ _CHECK_REDLINE( this )
+@@ -2751,8 +2759,10 @@ bool SwRedlineTbl::Insert( SwRangeRedline* p, bool bIns )
+ bool bRet = false;
+ if( p->HasValidRange() )
+ {
+- bRet = insert( p ).second;
+- p->CallDisplayFunc();
++ std::pair<_SwRedlineTbl::const_iterator, bool> rv = insert( p );
++ size_t nP = rv.first - begin();
++ bRet = rv.second;
++ p->CallDisplayFunc(0, nP);
+ }
+ else if( bIns )
+ bRet = InsertWithValidRanges( p );
+@@ -2771,7 +2781,7 @@ bool SwRedlineTbl::Insert( SwRangeRedline* p, sal_uInt16& rP, bool bIns )
+ std::pair<_SwRedlineTbl::const_iterator, bool> rv = insert( p );
+ rP = rv.first - begin();
+ bRet = rv.second;
+- p->CallDisplayFunc();
++ p->CallDisplayFunc(0, rP);
+ }
+ else if( bIns )
+ bRet = InsertWithValidRanges( p, &rP );
+@@ -2873,7 +2883,7 @@ bool SwRedlineTbl::InsertWithValidRanges( SwRangeRedline* p, sal_uInt16* pInsPos
+ pNew->HasValidRange() &&
+ Insert( pNew, nInsPos ) )
+ {
+- pNew->CallDisplayFunc();
++ pNew->CallDisplayFunc(0, nInsPos);
+ bAnyIns = true;
+ pNew = 0;
+ if( pInsPos && *pInsPos < nInsPos )
+@@ -3382,23 +3392,23 @@ bool SwRangeRedline::HasValidRange() const
+ return false;
+ }
+
+-void SwRangeRedline::CallDisplayFunc( sal_uInt16 nLoop )
++void SwRangeRedline::CallDisplayFunc(sal_uInt16 nLoop, size_t nMyPos)
+ {
+ switch( nsRedlineMode_t::REDLINE_SHOW_MASK & GetDoc()->GetRedlineMode() )
+ {
+ case nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE:
+- Show( nLoop );
++ Show(nLoop, nMyPos);
+ break;
+ case nsRedlineMode_t::REDLINE_SHOW_INSERT:
+- Hide( nLoop );
++ Hide(nLoop, nMyPos);
+ break;
+ case nsRedlineMode_t::REDLINE_SHOW_DELETE:
+- ShowOriginal( nLoop );
++ ShowOriginal(nLoop, nMyPos);
+ break;
+ }
+ }
+
+-void SwRangeRedline::Show( sal_uInt16 nLoop )
++void SwRangeRedline::Show(sal_uInt16 nLoop, size_t nMyPos)
+ {
+ if( 1 <= nLoop )
+ {
+@@ -3411,12 +3421,12 @@ void SwRangeRedline::Show( sal_uInt16 nLoop )
+ {
+ case nsRedlineType_t::REDLINE_INSERT: // Content has been inserted
+ bIsVisible = true;
+- MoveFromSection();
++ MoveFromSection(nMyPos);
+ break;
+
+ case nsRedlineType_t::REDLINE_DELETE: // Content has been deleted
+ bIsVisible = true;
+- MoveFromSection();
++ MoveFromSection(nMyPos);
+ break;
+
+ case nsRedlineType_t::REDLINE_FORMAT: // Attributes have been applied
+@@ -3430,7 +3440,7 @@ void SwRangeRedline::Show( sal_uInt16 nLoop )
+ }
+ }
+
+-void SwRangeRedline::Hide( sal_uInt16 nLoop )
++void SwRangeRedline::Hide(sal_uInt16 nLoop, size_t nMyPos)
+ {
+ SwDoc* pDoc = GetDoc();
+ RedlineMode_t eOld = pDoc->GetRedlineMode();
+@@ -3442,7 +3452,7 @@ void SwRangeRedline::Hide( sal_uInt16 nLoop )
+ case nsRedlineType_t::REDLINE_INSERT: // Content has been inserted
+ bIsVisible = true;
+ if( 1 <= nLoop )
+- MoveFromSection();
++ MoveFromSection(nMyPos);
+ break;
+
+ case nsRedlineType_t::REDLINE_DELETE: // Content has been deleted
+@@ -3451,7 +3461,7 @@ void SwRangeRedline::Hide( sal_uInt16 nLoop )
+ {
+ case 0: MoveToSection(); break;
+ case 1: CopyToSection(); break;
+- case 2: DelCopyOfSection(); break;
++ case 2: DelCopyOfSection(nMyPos); break;
+ }
+ break;
+
+@@ -3466,7 +3476,7 @@ void SwRangeRedline::Hide( sal_uInt16 nLoop )
+ pDoc->SetRedlineMode_intern( eOld );
+ }
+
+-void SwRangeRedline::ShowOriginal( sal_uInt16 nLoop )
++void SwRangeRedline::ShowOriginal(sal_uInt16 nLoop, size_t nMyPos)
+ {
+ SwDoc* pDoc = GetDoc();
+ RedlineMode_t eOld = pDoc->GetRedlineMode();
+@@ -3487,14 +3497,14 @@ void SwRangeRedline::ShowOriginal( sal_uInt16 nLoop )
+ {
+ case 0: MoveToSection(); break;
+ case 1: CopyToSection(); break;
+- case 2: DelCopyOfSection(); break;
++ case 2: DelCopyOfSection(nMyPos); break;
+ }
+ break;
+
+ case nsRedlineType_t::REDLINE_DELETE: // Inhalt wurde eingefuegt
+ bIsVisible = true;
+ if( 1 <= nLoop )
+- MoveFromSection();
++ MoveFromSection(nMyPos);
+ break;
+
+ case nsRedlineType_t::REDLINE_FORMAT: // Attributes have been applied
+@@ -3725,7 +3735,7 @@ void SwRangeRedline::CopyToSection()
+ }
+ }
+
+-void SwRangeRedline::DelCopyOfSection()
++void SwRangeRedline::DelCopyOfSection(size_t nMyPos)
+ {
+ if( pCntntSect )
+ {
+@@ -3772,7 +3782,7 @@ void SwRangeRedline::DelCopyOfSection()
+ // bDelLastPara condition above), only redlines before the
+ // current ones can be affected.
+ const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
+- sal_uInt16 n = rTbl.GetPos( this );
++ sal_uInt16 n = nMyPos;
+ OSL_ENSURE( n != USHRT_MAX, "How strange. We don't exist!" );
+ for( bool bBreak = false; !bBreak && n > 0; )
+ {
+@@ -3813,16 +3823,13 @@ void SwRangeRedline::DelCopyOfSection()
+ }
+ }
+
+-void SwRangeRedline::MoveFromSection()
++void SwRangeRedline::MoveFromSection(size_t nMyPos)
+ {
+ if( pCntntSect )
+ {
+ SwDoc* pDoc = GetDoc();
+ const SwRedlineTbl& rTbl = pDoc->GetRedlineTbl();
+ std::vector<SwPosition*> aBeforeArr, aBehindArr;
+- typedef std::map<sal_uInt16, SwRangeRedline*> IndexAndRange;
+- IndexAndRange aIndexAndRangeMap;
+- sal_uInt16 nMyPos = rTbl.GetPos( this );
+ OSL_ENSURE( this, "this is not in the array?" );
+ bool bBreak = false;
+ sal_uInt16 n;
+@@ -3834,14 +3841,12 @@ void SwRangeRedline::MoveFromSection()
+ {
+ SwRangeRedline* pRedl = rTbl[n];
+ aBehindArr.push_back(&pRedl->GetBound(true));
+- aIndexAndRangeMap.insert(std::make_pair(n, pRedl));
+ bBreak = false;
+ }
+ if( rTbl[ n ]->GetBound(false) == *GetPoint() )
+ {
+ SwRangeRedline* pRedl = rTbl[n];
+ aBehindArr.push_back(&pRedl->GetBound(false));
+- aIndexAndRangeMap.insert(std::make_pair(n, pRedl));
+ bBreak = false;
+ }
+ }
+@@ -3853,14 +3858,12 @@ void SwRangeRedline::MoveFromSection()
+ {
+ SwRangeRedline* pRedl = rTbl[n];
+ aBeforeArr.push_back(&pRedl->GetBound(true));
+- aIndexAndRangeMap.insert(std::make_pair(n, pRedl));
+ bBreak = false;
+ }
+ if( rTbl[ n ]->GetBound(false) == *GetPoint() )
+ {
+ SwRangeRedline* pRedl = rTbl[n];
+ aBeforeArr.push_back(&pRedl->GetBound(false));
+- aIndexAndRangeMap.insert(std::make_pair(n, pRedl));
+ bBreak = false;
+ }
+ }
+@@ -3935,13 +3938,6 @@ void SwRangeRedline::MoveFromSection()
+ *aBeforeArr[ n ] = *Start();
+ for( n = 0; n < aBehindArr.size(); ++n )
+ *aBehindArr[ n ] = *End();
+- SwRedlineTbl& rResortTbl = const_cast<SwRedlineTbl&>(rTbl);
+- for (auto& a : aIndexAndRangeMap)
+- {
+- // re-insert
+- rResortTbl.Remove(a.first);
+- rResortTbl.Insert(a.second);
+- }
+ }
+ else
+ InvalidateRange();
+diff --git a/sw/source/core/undo/unredln.cxx b/sw/source/core/undo/unredln.cxx
+index 283bf30..48b80c7 100644
+--- a/sw/source/core/undo/unredln.cxx
++++ b/sw/source/core/undo/unredln.cxx
+@@ -243,7 +243,7 @@ void SwUndoRedlineSort::UndoRedlineImpl(SwDoc & rDoc, SwPaM & rPam)
+ OSL_ENSURE( USHRT_MAX != nFnd && nFnd+1 < (sal_uInt16)rDoc.GetRedlineTbl().size(),
+ "could not find an Insert object" );
+ ++nFnd;
+- rDoc.GetRedlineTbl()[nFnd]->Show( 1 );
++ rDoc.GetRedlineTbl()[nFnd]->Show(1, nFnd);
+ }
+
+ {
+--
+1.9.3
+
diff --git a/libreoffice.spec b/libreoffice.spec
index 29c659a..73de4e8 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -376,6 +376,7 @@ Patch68: 0001-Resolves-fdo-88378-flipping-by-reversing-co-ord-syst.patch
Patch69: 0001-Resolves-rhbz-1179642-crash-in-GetFocus-with-empty-m.patch
Patch70: 0001-don-t-strip-font-names-of-apparent-script-suffixes-a.patch
Patch71: 0001-rhbz-1177022-vcl-fix-PDF-embedding-of-Type-1-fonts.patch
+Patch72: 0001-During-DocumentRedlineManager-SetRedlineMode-the-arr.patch
%define instdir %{_libdir}
%define baseinstdir %{instdir}/libreoffice
@@ -2347,7 +2348,7 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
%endif
%changelog
-* Tue Jan 27 2015 Caolán McNamara <caolanm at redhat.com> - 1:4.3.5.2-12-UNBUILT
+* Fri Jan 20 2015 Caolán McNamara <caolanm at redhat.com> - 1:4.3.5.2-12
- Resolves: rhbz#1136013 ExternalToolEdit crash
- font cache gets broken on adding an embedded font
- if we change the keys we have to resort based on the new keys
@@ -2356,6 +2357,7 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
- Resolves: rhbz#1179642 crash in GetFocus
- don't strip font names of apparent script suffixes
- Resolves: rhbz#1177022 fix PDF embedding of Type 1 fonts
+- make certain change-tracking odts not crash on deleting text
* Fri Jan 16 2015 Eike Rathke <erack at redhat.com> - 1:4.3.5.2-11
- Resolves: rhbz#1171828 fdo#86978 append formula cells to track instead of tree
More information about the scm-commits
mailing list