editeng/source/misc/svxacorr.cxx | 4 +++ sw/qa/extras/uiwriter/data/tdf83260-1.odt |binary sw/qa/extras/uiwriter/uiwriter.cxx | 35 ++++++++++++++++++++++++++++++ sw/source/filter/xml/swxml.cxx | 5 ++++ 4 files changed, 44 insertions(+)
New commits: commit e7c67eb093d1e099225eaccdaaf29eff1a4c9325 Author: Michael Stahl <mst...@redhat.com> Date: Wed Feb 14 12:57:49 2018 +0100 tdf#83260 sw: call CompressRedlines() in ODF import It's possible that an ODF document contains redlines that will be deduplicated by CompressRedlines(). If that happens during some editing operation, then a SwRedline will be deleted and the nodes array becomes smaller by at least 3 nodes; any Undo actions that were created prior to the operation that called CompressRedlines() will store invalid node indexes now and Undo will crash. So presumably it's a precondition of editing operations that CompressRedlines() is a no-op. Interestingly CompressRedlines() is also called from SwEditShell::Undo()/Redo(). Ensure it's a no-op later by calling CompressRedlines() immediately after load. (Hopefully this should also work for the Insert File case.) Add a test too. Change-Id: Iec8135cc60260ed5cfff05a196b5c92cc03265f9 Reviewed-on: https://gerrit.libreoffice.org/49721 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Michael Stahl <mst...@redhat.com> (cherry picked from commit 1c8efde4daea648204e3ba19f8edc01ef3e548bd) Reviewed-on: https://gerrit.libreoffice.org/49805 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> diff --git a/editeng/source/misc/svxacorr.cxx b/editeng/source/misc/svxacorr.cxx index 658e6c619f33..9c8eeb9d2dac 100644 --- a/editeng/source/misc/svxacorr.cxx +++ b/editeng/source/misc/svxacorr.cxx @@ -1233,6 +1233,7 @@ OUString SvxAutoCorrect::GetQuote( SvxAutoCorrDoc const & rDoc, sal_Int32 nInsPo return sRet; } +// WARNING: rText may become invalid, see comment below void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, sal_Int32 nInsPos, sal_Unicode cChar, bool bInsert, bool& io_bNbspRunNext, vcl::Window const * pFrameWin ) @@ -1343,6 +1344,9 @@ void SvxAutoCorrect::DoAutoCorrect( SvxAutoCorrDoc& rDoc, const OUString& rTxt, if( IsAutoCorrFlag( Autocorrect ) ) { + // WARNING ATTENTION: rTxt is an alias of the text node's OUString + // and becomes INVALID if ChgAutoCorrWord returns true! + // => use aPara/pPara to create a valid copy of the string! OUString aPara; OUString* pPara = IsAutoCorrFlag(CapitalStartSentence) ? &aPara : nullptr; diff --git a/sw/qa/extras/uiwriter/data/tdf83260-1.odt b/sw/qa/extras/uiwriter/data/tdf83260-1.odt new file mode 100644 index 000000000000..b6e144b57751 Binary files /dev/null and b/sw/qa/extras/uiwriter/data/tdf83260-1.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter.cxx b/sw/qa/extras/uiwriter/uiwriter.cxx index ffd2d4bba18d..3c6e0a04afd7 100644 --- a/sw/qa/extras/uiwriter/uiwriter.cxx +++ b/sw/qa/extras/uiwriter/uiwriter.cxx @@ -155,6 +155,7 @@ public: void testChineseConversionSimplifiedToTraditional(); void testFdo85554(); void testAutoCorr(); + void testTdf83260(); void testMergeDoc(); void testCreatePortions(); void testBookmarkUndo(); @@ -328,6 +329,7 @@ public: CPPUNIT_TEST(testChineseConversionSimplifiedToTraditional); CPPUNIT_TEST(testFdo85554); CPPUNIT_TEST(testAutoCorr); + CPPUNIT_TEST(testTdf83260); CPPUNIT_TEST(testMergeDoc); CPPUNIT_TEST(testCreatePortions); CPPUNIT_TEST(testBookmarkUndo); @@ -1407,6 +1409,39 @@ void SwUiWriterTest::testAutoCorr() CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getColumns()->getCount()); } +void SwUiWriterTest::testTdf83260() +{ + SwDoc* const pDoc(createDoc("tdf83260-1.odt")); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + SwAutoCorrect corr(*SvxAutoCorrCfg::Get().GetAutoCorrect()); + + // enabled but not shown + CPPUNIT_ASSERT(IDocumentRedlineAccess::IsHideChanges( + pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + CPPUNIT_ASSERT(IDocumentRedlineAccess::IsRedlineOn( + pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + CPPUNIT_ASSERT(!pDoc->getIDocumentRedlineAccess().GetRedlineTable().empty()); + + // the document contains redlines that are combined with CompressRedlines() + // if that happens during AutoCorrect then indexes in Undo are off -> crash + pWrtShell->Insert("tset"); + pWrtShell->AutoCorrect(corr, u' '); + sw::UndoManager& rUndoManager = pDoc->GetUndoManager(); + auto const nActions(rUndoManager.GetUndoActionCount()); + for (auto i = nActions; 0 < i; --i) + { + rUndoManager.Undo(); + } + for (auto i = nActions; 0 < i; --i) + { + rUndoManager.Redo(); + } + for (auto i = nActions; 0 < i; --i) + { + rUndoManager.Undo(); + } +} + void SwUiWriterTest::testMergeDoc() { SwDoc* const pDoc1(createDoc("merge-change1.odt")); diff --git a/sw/source/filter/xml/swxml.cxx b/sw/source/filter/xml/swxml.cxx index 652e84ef5ab8..dfedaa377a36 100644 --- a/sw/source/filter/xml/swxml.cxx +++ b/sw/source/filter/xml/swxml.cxx @@ -884,6 +884,11 @@ ErrCode XMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPaM, con // (First set bogus mode to make sure the mode in getIDocumentRedlineAccess().SetRedlineFlags() // is different from its previous mode.) rDoc.getIDocumentRedlineAccess().SetRedlineFlags_intern( ~nRedlineFlags ); + // must set flags to show delete so that CompressRedlines works + rDoc.getIDocumentRedlineAccess().SetRedlineFlags(nRedlineFlags|RedlineFlags::ShowDelete); + // tdf#83260 ensure that the first call of CompressRedlines after loading + // the document is a no-op by calling it now + rDoc.getIDocumentRedlineAccess().CompressRedlines(); rDoc.getIDocumentRedlineAccess().SetRedlineFlags( nRedlineFlags ); lcl_EnsureValidPam( rPaM ); // move Pam into valid content _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits